{"record":{"id":"bce953f248406293","repo":"medusajs/medusa","slug":"nonexistent-relations-were-passed-during-upsert","errorCode":null,"errorMessage":"Nonexistent relations were passed during upsert: ${nonexistentRelations}","messagePattern":"Nonexistent relations were passed during upsert: (.+?)","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/utils/src/dal/mikro-orm/mikro-orm-repository.ts","lineNumber":655,"sourceCode":"      }\n\n      // We want to convert a potential ORM model to a POJO\n      const normalizedData: any[] = await this.serialize(data)\n\n      const manager = this.getActiveManager<SqlEntityManager>(context)\n      // Handle the relations\n      const allRelations = manager\n        .getDriver()\n        .getMetadata()\n        .get(this.entity.name).relations\n\n      const nonexistentRelations = arrayDifference(\n        (config.relations as any) ?? [],\n        allRelations.map((r) => r.name)\n      )\n\n      if (nonexistentRelations.length) {\n        throw new MedusaError(\n          MedusaError.Types.INVALID_DATA,\n          `Nonexistent relations were passed during upsert: ${nonexistentRelations}`\n        )\n      }\n\n      // 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.\n      const reconstructedResponse: any[] = []\n      const originalDataMap = new Map<string, T>()\n\n      // Create only the top-level entity without the relations first\n      const toUpsert = normalizedData.map((entry) => {\n        // Make a copy of the data and remove undefined fields. The data is already a POJO due to the serialization above\n        const entryCopy = JSON.parse(JSON.stringify(entry))\n        const reconstructedEntry: any = {}\n\n        allRelations?.forEach((relation) => {\n          reconstructedEntry[relation.name] = this.handleRelationAssignment_(\n            relation,","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/utils/src/dal/mikro-orm/mikro-orm-repository.ts#L637-L673","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait productService.upsertProducts(data, {\n  relations: ['variants', 'images', 'meta'], // 'meta' is not a relation of Product\n})\n\n// after\nawait productService.upsertProducts(data, {\n  relations: ['variants', 'images'], // only real relations; scalars go in data\n})","handlingStrategy":"validation","validationCode":"const validRelations = manager.getMetadata(entityName).relations.map((r) => r.name)\nconst requested = config.relations ?? []\nconst invalid = requested.filter((r) => !validRelations.includes(r))\nif (invalid.length) throw new Error(`Invalid relations: ${invalid.join(\", \")}`)","typeGuard":"function isRelationName(name: string, entityMeta: any): boolean {\n  return entityMeta.relations.some((r: any) => r.name === name)\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["mikro-orm","upsert","relations","invalid-data","validation"],"backgroundTag":"invalid-relation-name","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}