n8n-io/n8n · error · TypeORMError

Cannot get entity metadata for the given alias "${this.name}

Error message

Cannot get entity metadata for the given alias "${this.name}"

What it means

The Alias.metadata getter throws when its private _metadata field is undefined. An Alias only carries EntityMetadata when it was resolved against a registered entity target; aliases created from raw table names, subquery strings, or SQL fragments have no metadata. Any code path that dereferences .metadata on such an alias (e.g. column resolution, relation lookup, alias.target) hits this guard.

Source

Thrown at packages/@n8n/typeorm/src/query-builder/Alias.ts:43

	}

	private _metadata?: EntityMetadata;

	get target(): Function | string {
		return this.metadata.target;
	}

	get hasMetadata(): boolean {
		return !!this._metadata;
	}

	set metadata(metadata: EntityMetadata) {
		this._metadata = metadata;
	}

	get metadata(): EntityMetadata {
		if (!this._metadata)
			throw new TypeORMError(`Cannot get entity metadata for the given alias "${this.name}"`);

		return this._metadata;
	}
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Register the target as a proper @Entity so the Alias resolves metadata; use the entity class or function reference instead of a raw table name.
  2. Use raw SQL fragments (addSelect('alias.column', 'key').getRawMany()) instead of property-path methods when querying non-entity tables.
  3. Check alias.hasMetadata before accessing alias.metadata if you must handle both cases.
  4. Ensure the DataSource that owns this QueryBuilder actually has the entity registered in its entities array.

Example fix

// before
const qb = dataSource
  .createQueryBuilder()
  .from('user_audit_log', 'log')
  .orderBy('log.createdAt'); // .orderBy may need metadata

// after — register entity, or use raw select
const rows = dataSource
  .createQueryBuilder()
  .select('log.created_at', 'createdAt')
  .from('user_audit_log', 'log')
  .orderBy('log.created_at')
  .getRawMany();
Defensive patterns

Strategy: type-guard

Validate before calling

const isEntityTarget = (target: unknown): target is Function | string =>
  typeof target === 'function' || (typeof target === 'string' && dataSource.entityMetadatas.some(m => m.targetName === target));
if (!isEntityTarget(target)) throw new Error('target is not a registered entity; use raw select');

Type guard

function aliasHasMetadata(alias: { hasMetadata: boolean }): alias is { hasMetadata: true; metadata: import('../metadata/EntityMetadata').EntityMetadata } {
  return alias.hasMetadata;
}

Prevention

When it happens

Trigger: Accessing .metadata (directly or via .target which calls it) on an Alias built from a raw table path in createQueryBuilder().from('raw_table_name') or a subquery alias. Internally raised when QueryBuilder resolves column paths against a FROM alias that has no entity, or when join metadata resolution fails to bind the target to a registered entity.

Common situations: Using createQueryBuilder on a raw/non-entity table and then calling methods that need entity columns (addSelect with property paths, orderBy on columns). Refactoring an entity into a View or raw table without registering it. Accidentally passing a string table name where an entity class/function is expected.

Related errors


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