n8n-io/n8n · error · TypeORMError

Referenced column ${joinColumn.referencedColumnName} was not

Error message

Referenced column ${joinColumn.referencedColumnName} was not found in entity ${relation.entityMetadata.name}

What it means

When building the junction (join) entity for a @ManyToMany relation, TypeORM resolves each `referencedColumnName` you declared in `@JoinTable({ joinColumns: [...] })` against `relation.entityMetadata.columns`. If the named column does not exist as a property on the owning entity, the resolution returns undefined and TypeORM throws, because it cannot wire the join table without knowing which column it points at.

Source

Thrown at packages/@n8n/typeorm/src/metadata-builder/JunctionEntityMetadataBuilder.ts:233

	/**
	 * Collects referenced columns from the given join column args.
	 */
	protected collectReferencedColumns(
		relation: RelationMetadata,
		joinTable: JoinTableMetadataArgs,
	): ColumnMetadata[] {
		const hasAnyReferencedColumnName = joinTable.joinColumns
			? joinTable.joinColumns.find((joinColumn) => !!joinColumn.referencedColumnName)
			: false;
		if (!joinTable.joinColumns || (joinTable.joinColumns && !hasAnyReferencedColumnName)) {
			return relation.entityMetadata.columns.filter((column) => column.isPrimary);
		} else {
			return joinTable.joinColumns.map((joinColumn) => {
				const referencedColumn = relation.entityMetadata.columns.find(
					(column) => column.propertyName === joinColumn.referencedColumnName,
				);
				if (!referencedColumn)
					throw new TypeORMError(
						`Referenced column ${joinColumn.referencedColumnName} was not found in entity ${relation.entityMetadata.name}`,
					);

				return referencedColumn;
			});
		}
	}

	/**
	 * 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)

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Verify the `referencedColumnName` string exactly matches a `@Column`/`@PrimaryColumn` property name on the OWNING entity of the @ManyToMany.
  2. If you want the junction to reference the inverse entity's column, move the `@JoinTable` to the other side and use `inverseJoinColumns`.
  3. Drop the explicit `referencedColumnName` and let TypeORM default to the primary key.

Example fix

// before — 'uuid' does not exist on the owning entity
@ManyToMany(() => Tag)
@JoinTable({ joinColumn: { name: 'post_id', referencedColumnName: 'uuid' } })
tags: Tag[];

// after — reference the actual PK property
@ManyToMany(() => Tag)
@JoinTable({ joinColumn: { name: 'post_id', referencedColumnName: 'id' } })
tags: Tag[];
Defensive patterns

Strategy: validation

Validate before calling

// Validate every @JoinTable referencedColumnName resolves on the owning entity
for (const m of dataSource.entityMetadatas) {
  for (const r of m.manyToManyRelations) {
    if (!r.joinTable?.joinColumns) continue;
    for (const jc of r.joinTable.joinColumns) {
      if (jc.referencedColumnName && !m.columns.some(c => c.propertyName === jc.referencedColumnName)) {
        throw new Error(`${m.name}: joinColumn references unknown column ${jc.referencedColumnName}`);
      }
    }
  }
}

Try / catch

try { await dataSource.initialize(); } catch (e) { if (e instanceof TypeORMError && /Referenced column.*was not found/) { /* check @JoinTable joinColumns */ } throw e; }

Prevention

When it happens

Trigger: Writing `@JoinTable({ joinColumn: { name: 'user_id', referencedColumnName: 'uuid' } })` when the owning entity has no `uuid` property (typo, or the column is on the inverse entity, or it was renamed). Referencing a column that lives in an embeddable that is not flattened into `columns`.

Common situations: Renaming an entity property but forgetting to update the @JoinTable referencedColumnName. Mixing up the owning vs inverse side and pointing referencedColumnName at a column on the wrong entity.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/dbe500ae292dff06. Report an issue: GitHub.