n8n-io/n8n · error · TypeORMError
Referenced column ${joinColumn.referencedColumnName} was not
Error message
Referenced column ${joinColumn.referencedColumnName} was not found in entity ${relation.inverseEntityMetadata.name} What it means
Symmetric to the owning-side check, this resolves `inverseJoinColumns[].referencedColumnName` against `relation.inverseEntityMetadata.ownColumns` (note: ownColumns only, not embedded/inherited columns). If the referenced property is not found directly on the inverse entity, the junction cannot be built and TypeORM throws.
Source
Thrown at packages/@n8n/typeorm/src/metadata-builder/JunctionEntityMetadataBuilder.ts:261
* Collects inverse referenced columns from the given join column args.
*/
protected collectInverseReferencedColumns(
relation: RelationMetadata,
joinTable: JoinTableMetadataArgs,
): ColumnMetadata[] {
const hasInverseJoinColumns = !!joinTable.inverseJoinColumns;
const hasAnyInverseReferencedColumnName = hasInverseJoinColumns
? joinTable.inverseJoinColumns!.find((joinColumn) => !!joinColumn.referencedColumnName)
: false;
if (!hasInverseJoinColumns || (hasInverseJoinColumns && !hasAnyInverseReferencedColumnName)) {
return relation.inverseEntityMetadata.primaryColumns;
} else {
return joinTable.inverseJoinColumns!.map((joinColumn) => {
const referencedColumn = relation.inverseEntityMetadata.ownColumns.find(
(column) => column.propertyName === joinColumn.referencedColumnName,
);
if (!referencedColumn)
throw new TypeORMError(
`Referenced column ${joinColumn.referencedColumnName} was not found in entity ${relation.inverseEntityMetadata.name}`,
);
return referencedColumn;
});
}
}
protected changeDuplicatedColumnNames(
junctionColumns: ColumnMetadata[],
inverseJunctionColumns: ColumnMetadata[],
) {
junctionColumns.forEach((junctionColumn) => {
inverseJunctionColumns.forEach((inverseJunctionColumn) => {
if (junctionColumn.givenDatabaseName === inverseJunctionColumn.givenDatabaseName) {
const junctionColumnName =
this.connection.namingStrategy.joinTableColumnDuplicationPrefix(
junctionColumn.propertyName,View on GitHub (pinned to 5ac6606e81)
Solutions
- Confirm `referencedColumnName` matches a column directly on the INVERSE entity (a @PrimaryColumn/@Column property, not one nested inside an @Embedded).
- Move the referenced column out of an embeddable onto the entity itself if you must reference it from a join table.
- Remove explicit `referencedColumnName` to default to the inverse entity's primary key.
Example fix
// before — 'slug' is not a top-level column on Tag
@JoinTable({
joinColumn: { name: 'post_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'tag_id', referencedColumnName: 'slug' },
})
// after
@JoinTable({
joinColumn: { name: 'post_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'tag_id', referencedColumnName: 'id' },
}) Defensive patterns
Strategy: validation
Validate before calling
for (const m of dataSource.entityMetadatas) {
for (const r of m.manyToManyRelations) {
if (!r.joinTable?.inverseJoinColumns) continue;
const inverseOwn = r.inverseEntityMetadata.ownColumns.map(c => c.propertyName);
for (const jc of r.joinTable.inverseJoinColumns) {
if (jc.referencedColumnName && !inverseOwn.includes(jc.referencedColumnName)) {
throw new Error(`inverseJoinColumn references unknown column ${jc.referencedColumnName} on ${r.inverseEntityMetadata.name}`);
}
}
}
} Try / catch
try { await dataSource.initialize(); } catch (e) { if (e instanceof TypeORMError && /Referenced column.*was not found in entity/) { /* inspect inverseJoinColumns + inverse entity ownColumns */ } throw e; } Prevention
- Remember the inverse side is resolved against `ownColumns` only — embeddeds won't match.
- Keep @JoinTable declarations on exactly one side of a @ManyToMany.
- Renaming an inverse-entity property? Update inverseJoinColumn.referencedColumnName the same commit.
When it happens
Trigger: Declaring `@JoinTable({ inverseJoinColumn: { name: 'tag_id', referencedColumnName: 'slug' } })` where the inverse entity has no top-level `slug` property (it might be in a @Embedded column, or only on a different entity, or simply mistyped).
Common situations: The inverse entity uses an embedded primary key whose properties are not in `ownColumns`. Renaming the inverse entity's PK without updating the @JoinTable. Confusing the joinColumns vs inverseJoinColumns slots.
Related errors
- Referenced column ${joinColumn.referencedColumnName} was not
- OnUpdateType "${relation.onUpdate}" is not valid for ${drive
- Relation ${entityMetadata.name}#${relation.propertyName} and
- Circular relations detected: ${path}. To resolve this issue
- Circular eager relations are disallowed. ${entityMetadata.ta
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/bd8f7336cc45c520.
Report an issue: GitHub.