{"record":{"id":"5b1da623aa5a2177","repo":"medusajs/medusa","slug":"unable-to-soft-delete-the-relation-name-circul","errorCode":null,"errorMessage":"Unable to soft delete the ${relation.name}. Circular dependency detected: ${circularDependencyStr}","messagePattern":"Unable to soft delete the (.+?)\\. Circular dependency detected: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/utils/src/dal/mikro-orm/utils.ts","lineNumber":41,"sourceCode":"  )\n\n  for (const relation of relationsToCascade) {\n    const branchVisited = new Set(Array.from(visited))\n\n    const relationEntity =\n      typeof relation.entity === \"function\"\n        ? relation.entity()\n        : relation.entity\n    const isSelfCircularDependency = isString(relationEntity)\n      ? entityMetadata.className === relationEntity\n      : entityMetadata.class === relationEntity\n\n    if (!isSelfCircularDependency && branchVisited.has(relation.name)) {\n      const dependencies = Array.from(visited)\n      dependencies.push(entityMetadata.className)\n      const circularDependencyStr = dependencies.join(\" -> \")\n\n      throw new Error(\n        `Unable to soft delete the ${relation.name}. Circular dependency detected: ${circularDependencyStr}`\n      )\n    }\n    branchVisited.add(relation.name)\n\n    const relationEntityMetadata = manager\n      .getDriver()\n      .getMetadata()\n      .get(relation.type)\n\n    detectCircularDependency(\n      manager,\n      relationEntityMetadata,\n      branchVisited,\n      isSelfCircularDependency\n    )\n  }\n}","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/utils/src/dal/mikro-orm/utils.ts#L23-L59","documentation":"detectCircularDependency walks the entity relation graph before recursively soft-deleting related records and throws this plain Error when it finds a cycle (A -> B -> ... -> A) that cannot be safely ordered for deletion. It is raised from mikro-orm/utils.ts during mikroOrmUpdateDeletedAtRecursively, which is used by repository soft-delete cascades.","triggerScenarios":"Calling softDelete on an entity whose softDeletable relation chain forms a cycle — e.g. entity A has a soft-deletable many-to-one to B while B also has a soft-deletable relation back to A; custom modules that add reciprocal soft-deletable relations between two models.","commonSituations":"Adding a new relation to a module data model and marking it soft-deletable without checking the inverse side already cascades back; customization that links e.g. order <-> fulfillment-ish tables in both directions with cascade soft deletes; version upgrades where new relations made an existing pair cyclic.","solutions":["Inspect the chain printed in the message (A -> B -> A) and remove one direction from the soft-deletable/cascade configuration so the graph becomes acyclic.","Soft-delete each side explicitly in separate ordered service calls instead of relying on recursive cascade.","If the inverse relation is only needed for querying, keep it on the model but exclude it from the soft-delete cascade configuration.","After changing the model, regenerate the module migration if the change affects the schema."],"exampleFix":"// before (module model link config — both directions soft-deletable)\nsoftDelete: () => true // on A.b AND on B.a  => cycle\n\n// after\n// A.b keeps cascade:\n//   b: one({ entity: () => B, ... })\n// B.a becomes a plain relation without soft-delete cascade (or is soft-deleted manually after A)","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await service.softDelete(ids)\n} catch (err) {\n  if (err instanceof Error && /Circular dependency detected/.test(err.message)) {\n    // fallback: soft-delete each side explicitly in a safe order\n    for (const id of ids) await service.softDelete(id, { relations: acyclicSubset })\n  } else throw err\n}","preventionTips":["Keep soft-delete cascade configuration acyclic when designing reciprocal relations.","Audit module link/softDelete flags after adding new relations between existing models.","Prefer explicit ordered soft-deletes in workflows over relying on deep recursive cascade."],"tags":["mikro-orm","soft-delete","circular-dependency","relations","cascade"],"backgroundTag":"circular-foreign-key-cascade","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}