Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating a Salesforce account parent-child circular relationship structure and error
Admin

Salesforce Account Parent-Child Circular Relationship: What Happens When You Create a Circular Parent?

The short answer

Salesforce blocks circular parent-child relationships on Accounts by enforcing the hierarchy as a directed acyclic graph. Any UI save, Apex operation, or API call that tries to create a recursive parent chain is rejected with an error.

Key takeaways Catch circular account hierarchies before they save by adding a server-side check in a before-save Flow or an Apex trigger. Validate parent-child hierarchies during external ETL or data-load pre-processing so cycles never reach Salesforce. Traverse hierarchies with bulkified queries across batches of parents instead of running SOQL inside a loop. Chunk the traversal for deep account structures so you avoid infinite loops and stay inside governor limits.

Context

You create two Account records in Salesforce, a1 and a2. You set a2 as the parent of a1 (a1.ParentId = a2.Id). Then you try to make a1 the parent of a2 (a2.ParentId = a1.Id). What happens?

Short answer

Salesforce prevents circular parent-child relationships. Once a2 is the parent of a1, an attempt to make a1 the parent of a2 is blocked and the platform returns a validation or API error. Salesforce enforces the Account hierarchy as a directed acyclic graph (a tree), so cycles are not allowed.

Why Salesforce blocks this

A parent-child cycle would create an infinite loop in hierarchy traversals (ancestors and descendants) and break assumptions used by UI features such as Parent Account and Account Hierarchy, along with sharing calculations, rollups, and many other system operations. Enforcing a strict non-recursive parent chain is how Salesforce keeps data integrity and predictable behavior.

How the error appears

In the Salesforce UI you will typically get an error when saving the Account record, telling you a recursive or circular relationship is not allowed. Through the API (SOAP or REST) or Apex, the save or update fails with an error indicating a recursive relationship or an invalid ParentId update. The exact wording varies across releases and APIs, but the effect is the same: the transaction is rejected.

How to detect and prevent circular references programmatically

If you need to enforce this yourself, or to catch potential cycles early for bulk updates, integrations, or friendlier messages, add a server-side check (an Apex trigger or a before-save flow) that walks the parent chain and confirms the new parent is not a descendant of the current record.

Example: simple Apex pre-check (conceptual)

// Pseudocode - do NOT paste to production without testing
for (Account a : Trigger.new) {
    Id newParentId = a.ParentId;
    if (newParentId == null) continue;

    // Walk up the parent chain from newParentId and look for the current account Id
    Id cursor = newParentId;
    while (cursor != null) {
        if (cursor == a.Id) {
            a.addError('Cannot set parent: this would create a circular account hierarchy.');
            break;
        }
        // Query parent of cursor
        Account p = [SELECT ParentId FROM Account WHERE Id = :cursor LIMIT 1];
        cursor = p.ParentId;
        // Optional: add safety counter to avoid infinite loops
    }
}

Two things to watch in real code. Use bulk-safe patterns and avoid one SOQL per loop: collect parent Ids, fetch the accounts in batches, then iterate in memory. For very deep hierarchies or large data volumes, use an iterative algorithm that loads parent levels in chunks so you stay within governor limits.

Best practices

  • Enforce the check in a before-insert or before-update Apex trigger, or a server-side Flow, to block cycles.
  • Give users clear UI validation messages so they understand why the save failed.
  • When doing data loads, validate parent chains in your ETL or pre-processing step and catch cycles before they reach Salesforce.
  • If you need fast ancestor or descendant queries, consider storing computed hierarchy metadata (e.g., depth, ancestor list), and make sure the metadata update logic prevents cycles too.

Keywords

Salesforce account hierarchy, circular parent relationship, ParentId, recursive relationship, Apex trigger, account parent-child, data integrity

Frequently asked questions

What happens when you create a circular parent Account relationship in Salesforce?

Salesforce blocks the change and rejects the transaction with a validation or API error about an invalid ParentId update or a recursive relationship. That enforcement stops hierarchy traversals from looping forever and protects data integrity across sharing rules, UI views, and rollups.

Why does Salesforce block circular parent-child relationships?

Cycles would send hierarchy traversals into infinite loops and break core platform features such as Account Hierarchy views, sharing calculations, and rollups. Salesforce enforces hierarchies strictly as directed acyclic graphs so system behavior stays predictable.

How do you detect and prevent circular Account relationships in Apex?

Write a before-insert or before-update trigger that walks the parent chain from the new ParentId and checks that it is not a descendant of the current record. For deep hierarchies and bulk operations, collect parent IDs into batches and query them iteratively outside the loop.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment