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
- 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.
- Use raw SQL fragments (addSelect('alias.column', 'key').getRawMany()) instead of property-path methods when querying non-entity tables.
- Check alias.hasMetadata before accessing alias.metadata if you must handle both cases.
- 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
- Prefer createQueryBuilder(Entity, 'alias') with a registered entity over raw table strings.
- For raw tables, use getRawMany() with explicit column-name selects, not property-path methods.
- Ensure every entity is listed in DataSourceOptions.entities.
- Guard metadata-dependent calls with alias.hasMetadata before access.
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
- Entity "${entityMetadata.name}" does not have a primary colu
- Relation with property path ${this.relationPropertyPath} in
- Cannot get junction table for join without relation.
- Main alias is not set
- Entity where values should be inserted is not specified. Cal
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/c8e08a8d205be563.
Report an issue: GitHub.