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

  1. De-duplicate join specs by target.table before submitting the query
  2. If you need the same table twice, alias it via a subquery or restructure as separate queries
  3. 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

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


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/205b0781a2eea90e. Report an issue: GitHub.