medusajs/medusa · error · MedusaError
Duplicate cross-module join target table "${join.target.tabl
Error message
Duplicate cross-module join target table "${join.target.table}". Each join must target a unique table. What it means
When composing cross-module joins in a single SQL query, each join must target a distinct table. Two join specs targeting the same table would produce ambiguous SQL, so Medusa validates and rejects duplicates with INVALID_DATA.
Source
Thrown at packages/core/utils/src/dal/mikro-orm/cross-module-query/helpers.ts:163
usedBaseAliases.set(baseAlias, usageCount + 1)
const alias =
usageCount === 0 ? baseAlias : `${baseAlias}_${usageCount + 1}`
return {
...join,
alias,
}
})
}
function assertValidCrossModuleJoins(
crossModuleJoins: CrossModuleJoinSpec[]
): void {
const targetTables = new Set<string>()
for (const join of crossModuleJoins) {
if (targetTables.has(join.target.table)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Duplicate cross-module join target table "${join.target.table}". Each join must target a unique table.`
)
}
targetTables.add(join.target.table)
}
for (const join of crossModuleJoins) {
if (!join.parent) {
continue
}
if (join.parent === join.target.table) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Cross-module join for "${join.target.table}" cannot be its own parent.`
)View on GitHub (pinned to 5e06e544a2)
Solutions
- De-duplicate join specs by target.table before submitting the query
- If you need the same table twice, alias it via a subquery or restructure as separate queries
- Validate user-supplied filter shapes against a fixed schema
Example fix
// before joins: [j1, j2] // both target "variant" // after const joins = [...new Map(allJoins.map(j => [j.target.table, j])).values()]
Defensive patterns
Strategy: validation
Validate before calling
const seen = new Set<string>()
for (const j of joins) { if (seen.has(j.target.table)) throw new Error(`duplicate join target ${j.target.table}`); seen.add(j.target.table) } Prevention
- De-duplicate joins by target.table in your query builder
- Constrain user-supplied filters to a fixed set of relations
When it happens
Trigger: Calling resolveCrossModuleJoins / building a query whose `joins` array contains two entries with the same `target.table`, e.g. joining product_variant twice in one filter set.
Common situations: Dynamically generated joins from user-selected filters that add the same relation twice, or copy-pasted join specs.
Related errors
- Cross-module join for "${join.target.table}" cannot be its o
- Cross-module join for "${join.target.table}" references unkn
- --paths must be a directory - ${additionalPath}
- --base must be a file - ${baseFile}
- insufficient_inventory
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/205b0781a2eea90e.
Report an issue: GitHub.