{"record":{"id":"26acaf133103561e","repo":"medusajs/medusa","slug":"cross-module-join-for-join-target-table-canno","errorCode":null,"errorMessage":"Cross-module join for \"${join.target.table}\" cannot be its own parent.","messagePattern":"Cross-module join for \"(.+?)\" cannot be its own parent\\.","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/utils/src/dal/mikro-orm/cross-module-query/helpers.ts","lineNumber":178,"sourceCode":"\n  for (const join of crossModuleJoins) {\n    if (targetTables.has(join.target.table)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Duplicate cross-module join target table \"${join.target.table}\". Each join must target a unique table.`\n      )\n    }\n\n    targetTables.add(join.target.table)\n  }\n\n  for (const join of crossModuleJoins) {\n    if (!join.parent) {\n      continue\n    }\n\n    if (join.parent === join.target.table) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Cross-module join for \"${join.target.table}\" cannot be its own parent.`\n      )\n    }\n\n    if (!targetTables.has(join.parent)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Cross-module join for \"${join.target.table}\" references unknown parent target table \"${join.parent}\".`\n      )\n    }\n  }\n}\n","sourceCodeStart":160,"sourceCodeEnd":192,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/utils/src/dal/mikro-orm/cross-module-query/helpers.ts#L160-L192","documentation":"Cross-module join validation: a join whose declared parent is the same as its own target table would create a self-referential cycle the resolver cannot order, so it is rejected.","triggerScenarios":"A join spec where `join.parent === join.target.table`, e.g. { target: { table: \"price\" }, parent: \"price\" }, typically from programmatically derived parents defaulting to the same table.","commonSituations":"Auto-generated join configs that fall back to the current table when no parent is detected.","solutions":["Set the parent to the actual driving table of the join, or omit `parent` when the join hangs off the root","Fix the generator that defaults parent to target.table"],"exampleFix":"// before\n{ target: { table: \"price\" }, parent: \"price\" }\n// after\n{ target: { table: \"price\" } } // joins off the root entity","handlingStrategy":"validation","validationCode":"for (const j of joins) if (j.parent === j.target.table) throw new Error(`self-parent join on ${j.target.table}`)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Omit parent when joining off the root entity","Unit-test generated join specs"],"tags":["query","joins","cross-module","validation"],"backgroundTag":"self-referencing-join","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}