{"record":{"id":"fcbda485159f357b","repo":"n8n-io/n8n","slug":"add-operation-is-only-supported-for-many-to-many-a-fcbda4","errorCode":null,"errorMessage":"Add operation is only supported for many-to-many and one-to-many relations. However given \"${relation.propertyPath}\" has ${relation.relationType} relation. Use .set(null) method instead.","messagePattern":"Add operation is only supported for many-to-many and one-to-many relations\\. However given \"(.+?)\" has (.+?) relation\\. Use \\.set\\(null\\) method instead\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/query-builder/RelationQueryBuilder.ts","lineNumber":133,"sourceCode":"\t * Removes (unbinds) given value from entity relation.\n\t * Value can be entity, entity id or entity id map (if entity has composite ids).\n\t * Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids).\n\t * Works only for many-to-many and one-to-many relations.\n\t * For many-to-one and one-to-one use #set method instead.\n\t */\n\tasync remove(value: any | any[]): Promise<void> {\n\t\tif (Array.isArray(value) && value.length === 0) return;\n\n\t\tconst relation = this.expressionMap.relationMetadata;\n\n\t\tif (!this.expressionMap.of)\n\t\t\t// todo: move this check before relation query builder creation?\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`Entity whose relation needs to be set is not set. Use .of method to define whose relation you want to set.`,\n\t\t\t);\n\n\t\tif (relation.isManyToOne || relation.isOneToOne)\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`Add operation is only supported for many-to-many and one-to-many relations. ` +\n\t\t\t\t\t`However given \"${relation.propertyPath}\" has ${relation.relationType} relation. ` +\n\t\t\t\t\t`Use .set(null) method instead.`,\n\t\t\t);\n\n\t\tconst remover = new RelationRemover(this, this.expressionMap);\n\t\treturn remover.remove(value);\n\t}\n\n\t/**\n\t * Adds (binds) and removes (unbinds) given values to/from entity relation.\n\t * Value can be entity, entity id or entity id map (if entity has composite ids).\n\t * Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids).\n\t * Works only for many-to-many and one-to-many relations.\n\t * For many-to-one and one-to-one use #set method instead.\n\t */\n\tasync addAndRemove(added: any | any[], removed: any | any[]): Promise<void> {\n\t\tawait this.remove(removed);","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/query-builder/RelationQueryBuilder.ts#L115-L151","documentation":"RelationQueryBuilder.remove supports only many-to-many and one-to-many. If the resolved relation is many-to-one or one-to-one it throws TypeORMError, but — unlike .add — points the developer to .set(null) because clearing a single-valued FK is the correct unbind operation for those relation types. Note the message string still says 'Add operation' which is a copy-paste bug in the upstream message.","triggerScenarios":"qb.relation(User,'profile').of(u).remove(profile) on a @OneToOne; .remove() on a @ManyToOne like User.organization.","commonSituations":"Decorator confusion; developer assumes .remove works on all relations; intent is actually to null out an FK but the wrong API was chosen.","solutions":["Use .set(null) to unbind a single-valued relation: qb.relation(User,'profile').of(u).set(null).","Confirm the decorator on relation.propertyPath to be sure which API applies.","If the intent really is collection removal, switch the relation target to the collection side."],"exampleFix":"// before\nawait qb.relation(User,'profile').of(u).remove(profile); // one-to-one\n// after\nawait qb.relation(User,'profile').of(u).set(null);","handlingStrategy":"type-guard","validationCode":"function supportsRemove(ds: DataSource, target: Function, path: string): boolean {\n  const r = ds.getMetadata(target).findRelationWithPropertyPath(path);\n  return !!r && (r.isManyToMany || r.isOneToMany);\n}","typeGuard":"function isCollectionRelation(ds: DataSource, target: Function, path: string): boolean {\n  const r = ds.getMetadata(target).findRelationWithPropertyPath(path);\n  return !!r && (r.relationType === 'many-to-many' || r.relationType === 'one-to-many');\n}","tryCatchPattern":null,"preventionTips":["Remember that single-valued relations unbind via .set(null), not .remove().","Wrap relation APIs behind a service that maps intent to the correct TypeORM method."],"tags":["typeorm","relation-query-builder","remove","relation-type"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}