{"record":{"id":"ae9449220b1888f0","repo":"n8n-io/n8n","slug":"entity-metadata-for-entitymetadata-name-relat","errorCode":null,"errorMessage":"Entity metadata for ${entityMetadata.name}#${relation.propertyPath} was not found. Check if you specified a correct entity object and if it's connected in the connection options.","messagePattern":"Entity metadata for (.+?)#(.+?) was not found\\. Check if you specified a correct entity object and if it's connected in the connection options\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"critical","filePath":"packages/@n8n/typeorm/src/metadata-builder/EntityMetadataBuilder.ts","lineNumber":833,"sourceCode":"\t}\n\n\t/**\n\t * Computes entity metadata's relations inverse side properties.\n\t */\n\tprotected computeInverseProperties(\n\t\tentityMetadata: EntityMetadata,\n\t\tentityMetadatas: EntityMetadata[],\n\t) {\n\t\tentityMetadata.relations.forEach((relation) => {\n\t\t\t// compute inverse side (related) entity metadatas for all relation metadatas\n\t\t\tconst inverseEntityMetadata = entityMetadatas.find(\n\t\t\t\t(m) =>\n\t\t\t\t\tm.target === relation.type ||\n\t\t\t\t\t(typeof relation.type === 'string' &&\n\t\t\t\t\t\t(m.targetName === relation.type || m.givenTableName === relation.type)),\n\t\t\t);\n\t\t\tif (!inverseEntityMetadata)\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t'Entity metadata for ' +\n\t\t\t\t\t\tentityMetadata.name +\n\t\t\t\t\t\t'#' +\n\t\t\t\t\t\trelation.propertyPath +\n\t\t\t\t\t\t\" was not found. Check if you specified a correct entity object and if it's connected in the connection options.\",\n\t\t\t\t);\n\n\t\t\trelation.inverseEntityMetadata = inverseEntityMetadata;\n\t\t\trelation.inverseSidePropertyPath = relation.buildInverseSidePropertyPath();\n\n\t\t\t// and compute inverse relation and mark if it has such\n\t\t\trelation.inverseRelation = inverseEntityMetadata.relations.find(\n\t\t\t\t(foundRelation) => foundRelation.propertyPath === relation.inverseSidePropertyPath,\n\t\t\t);\n\t\t});\n\t}\n\n\t/**","sourceCodeStart":815,"sourceCodeEnd":851,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/metadata-builder/EntityMetadataBuilder.ts#L815-L851","documentation":"Thrown in EntityMetadataBuilder.computeInverseEntitiesMap (the loop over entityMetadata.relations) when no registered entity metadata matches the relation's type. The matcher tries m.target === relation.type, then string fallback (targetName or givenTableName equal to relation.type). If none of the registered entity metadatas satisfies any branch, TypeORMError fires naming entityMetadata.name and relation.propertyPath.","triggerScenarios":"Declaring @ManyToOne(() => MissingEntity) where MissingEntity is not in the DataSource entities list; using a string relation type that matches no targetName/givenTableName; circular import that resolves the relation function to undefined.","commonSituations":"Forgetting to register an entity in DataSource options (entities: [...]); broken import returning undefined due to a circular dependency; renaming an entity class without updating string relation types; tree-shaking stripping an entity.","solutions":["Add the missing entity to the DataSource entities array (or enable glob entity loading that includes it).","If using arrow-function relation types, confirm the import resolves without a circular dependency (use string type or deferred import).","For string-typed relations, ensure the value equals the target's targetName or givenTableName exactly."],"exampleFix":"// before\n@Entity()\nexport class Post {\n  @ManyToOne(() => Author) // Author not in DataSource.entities\n  author: Author;\n}\n\n// after\nnew DataSource({\n  entities: [Post, Author], // register it\n});","handlingStrategy":"validation","validationCode":"function validateRelationTargets(\n  entityClasses: Function[],\n  dataSource: DataSource,\n): string[] {\n  const registered = new Set(\n    dataSource.entityMetadatas.map((m) => (m.target as Function)?.name),\n  );\n  const problems: string[] = [];\n  for (const cls of entityClasses) {\n    const meta = dataSource.getMetadata(cls);\n    for (const rel of meta.relations) {\n      if (typeof rel.type === 'function') {\n        const name = (rel.type as Function).name;\n        if (!registered.has(name)) {\n          problems.push(`${meta.targetName}.${rel.propertyPath} -> unregistered target ${name}`);\n        }\n      } else if (typeof rel.type === 'string') {\n        const hit = dataSource.entityMetadatas.some(\n          (m) => m.targetName === rel.type || m.givenTableName === rel.type,\n        );\n        if (!hit) problems.push(`${meta.targetName}.${rel.propertyPath} -> unregistered string target '${rel.type}'`);\n      }\n    }\n  }\n  return problems;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await dataSource.initialize();\n} catch (err) {\n  if (err.message.includes('Entity metadata for') && err.message.includes('was not found')) {\n    // log the entity#relationPath pair and check DataSource.entities\n  }\n  throw err;\n}","preventionTips":["Register every entity (and every relation target) in the DataSource entities array; prefer an explicit list over fragile globbing.","For circular imports, use arrow-function relation types so the import defers evaluation.","Add a boot test that enumerates entityMetadatas and asserts every relation target is registered."],"tags":["relation","inverse-side","entity-registration","startup"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}