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
- 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.
- If the name looks correct, verify you are upserting the entity you think you are (generic repositories reuse upsertWithReplace across many entities).
- 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
- Derive relation lists from entity metadata instead of hard-coding them.
- Unit-test custom upsert configs against the model's relation set.
- Remember DTO fields are not necessarily relations — check the model definition.
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
- Many-to-one relation ${relation.name} must be set with an ID
- Cannot set value ${value} for ${columnName}.
- Unable to soft delete the ${relation.name}. Circular depende
- Invalid geo zone type: ${geoZone.type}
- --paths must be a directory - ${additionalPath}
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/bce953f248406293.
Report an issue: GitHub.