{"record":{"id":"07f113624e6a94b2","repo":"medusajs/medusa","slug":"cross-module-join-for-join-target-table-refer","errorCode":null,"errorMessage":"Cross-module join for \"${join.target.table}\" references unknown parent target table \"${join.parent}\".","messagePattern":"Cross-module join for \"(.+?)\" references unknown parent target table \"(.+?)\"\\.","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/utils/src/dal/mikro-orm/cross-module-query/helpers.ts","lineNumber":185,"sourceCode":"    }\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":167,"sourceCodeEnd":192,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/utils/src/dal/mikro-orm/cross-module-query/helpers.ts#L167-L192","documentation":"Cross-module join validation: a join declares a `parent` table that is not among the target tables of the other joins nor the root, so the dependency chain cannot be resolved and the query is rejected.","triggerScenarios":"A join spec like { target: { table: \"price\" }, parent: \"collection\" } where no other join targets \"collection\"; usually a typo or a missing intermediate join.","commonSituations":"Hand-written join configs, renamed tables across module versions, or omitting a join that the parent chain requires.","solutions":["Add the missing join that targets the referenced parent table","Correct the parent name to match an existing join's target.table exactly (case/alias sensitive)"],"exampleFix":"// before\njoins: [{ target: { table: \"price\" }, parent: \"collection\" }]\n// after\njoins: [\n  { target: { table: \"collection\" } },\n  { target: { table: \"product\" }, parent: \"collection\" },\n  { target: { table: \"price\" }, parent: \"product\" },\n]","handlingStrategy":"validation","validationCode":"const targets = new Set(joins.map(j => j.target.table))\nfor (const j of joins) if (j.parent && !targets.has(j.parent)) throw new Error(`unknown parent ${j.parent}`)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the join chain is connected to the root before submitting","Keep table names in constants to avoid typos"],"tags":["query","joins","cross-module","validation"],"backgroundTag":"unknown-join-parent","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}