medusajs/medusa · error · MedusaError

Nonexistent relations were passed during upsert: ${nonexiste

Error message

Nonexistent relations were passed during upsert: ${nonexistentRelations}

What it means

Thrown by MikroORM's upsertWithReplace in Medusa's base repository before any DB work happens: the `relations` array passed in the upsert config contains at least one relation name that is not defined on the entity's metadata. It is a MedusaError of type INVALID_DATA and is purely an input-contract violation against the entity's relation set.

Source

Thrown at packages/core/utils/src/dal/mikro-orm/mikro-orm-repository.ts:655

      }

      // We want to convert a potential ORM model to a POJO
      const normalizedData: any[] = await this.serialize(data)

      const manager = this.getActiveManager<SqlEntityManager>(context)
      // Handle the relations
      const allRelations = manager
        .getDriver()
        .getMetadata()
        .get(this.entity.name).relations

      const nonexistentRelations = arrayDifference(
        (config.relations as any) ?? [],
        allRelations.map((r) => r.name)
      )

      if (nonexistentRelations.length) {
        throw new MedusaError(
          MedusaError.Types.INVALID_DATA,
          `Nonexistent relations were passed during upsert: ${nonexistentRelations}`
        )
      }

      // We want to response with all the data including the IDs in the same order as the input. We also include data that was passed but not processed.
      const reconstructedResponse: any[] = []
      const originalDataMap = new Map<string, T>()

      // Create only the top-level entity without the relations first
      const toUpsert = normalizedData.map((entry) => {
        // Make a copy of the data and remove undefined fields. The data is already a POJO due to the serialization above
        const entryCopy = JSON.parse(JSON.stringify(entry))
        const reconstructedEntry: any = {}

        allRelations?.forEach((relation) => {
          reconstructedEntry[relation.name] = this.handleRelationAssignment_(
            relation,

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Compare every entry in config.relations against the entity's actual relation names (entity metadata / model definition) and remove the invalid ones — the error message lists exactly which names failed the diff.
  2. If the name looks correct, verify you are upserting the entity you think you are (generic repositories reuse upsertWithReplace across many entities).
  3. If the field is a scalar column, remove it from `relations` and set it directly in the data payload instead.

Example fix

// before
await productService.upsertProducts(data, {
  relations: ['variants', 'images', 'meta'], // 'meta' is not a relation of Product
})

// after
await productService.upsertProducts(data, {
  relations: ['variants', 'images'], // only real relations; scalars go in data
})
Defensive patterns

Strategy: validation

Validate before calling

const validRelations = manager.getMetadata(entityName).relations.map((r) => r.name)
const requested = config.relations ?? []
const invalid = requested.filter((r) => !validRelations.includes(r))
if (invalid.length) throw new Error(`Invalid relations: ${invalid.join(", ")}`)

Type guard

function isRelationName(name: string, entityMeta: any): boolean {
  return entityMeta.relations.some((r: any) => r.name === name)
}

Prevention

When it happens

Trigger: Calling a module service upsert with a config like { relations: ['variants', 'images', 'metadata'] } where 'metadata' is not a relation of the entity (it may be a scalar column or not exist at all); typo'd relation names; passing property names of the DTO that are not MikroORM relations.

Common situations: Custom services or scripts building upsert configs dynamically; copying a relation list from one entity type to another (e.g. from product to collection); assuming a field is a relation because it appears in the returned DTO, when it is actually a scalar or computed field.

Related errors


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