typeorm/typeorm · error · TypeORMError
Entity to work with is not specified!
Error message
Entity to work with is not specified!
What it means
Thrown by the relationMetadata getter on QueryExpressionMap when mainAlias is null. This getter is used by RelationQueryBuilder (e.g. .relation(...).set/.add/.remove) which requires an owning entity. Without a main alias there is no entity to resolve relations against.
Source
Thrown at src/query-builder/QueryExpressionMap.ts:465
return alias
}
findColumnByAliasExpression(
aliasExpression: string,
): ColumnMetadata | undefined {
const [aliasName, propertyPath] = aliasExpression.split(".")
const alias = this.findAliasByName(aliasName)
return alias.metadata.findColumnWithPropertyName(propertyPath)
}
/**
* Gets relation metadata of the relation this query builder works with.
*
* todo: add proper exceptions
*/
get relationMetadata(): RelationMetadata {
if (!this.mainAlias)
throw new TypeORMError(`Entity to work with is not specified!`) // todo: better message
const relationMetadata =
this.mainAlias.metadata.findRelationWithPropertyPath(
this.relationPropertyPath,
)
if (!relationMetadata)
throw new TypeORMError(
`Relation ${this.relationPropertyPath} was not found in entity ${this.mainAlias.name}`,
) // todo: better message
return relationMetadata
}
/**
* Copies all properties of the current QueryExpressionMap into a new one.
* Useful when QueryBuilder needs to create a copy of itself.
*/
clone(): QueryExpressionMap {View on GitHub (pinned to 04ff4daedc)
Solutions
- Always start relation operations from an entity-bound builder: dataSource.createQueryBuilder(User, 'user').relation(User, 'posts').
- Use the repository shorthand repo.relation(...) which binds the entity automatically.
- Ensure mainAlias is set before any .relation/.of/.set call.
Example fix
// before
await dataSource.createQueryBuilder()
.relation(User, 'posts').of(user).set(post); // 492
// after
await dataSource.createQueryBuilder(User, 'user')
.relation(User, 'posts').of(user).set(post);
// or simpler:
await repo.relation('posts').of(user).add(post); Defensive patterns
Strategy: validation
Validate before calling
function assertRelationBuilderHasMainAlias(qb) {
if (!qb.expressionMap.mainAlias) throw new Error('Relation ops require an entity main alias; use repo.relation() or createQueryBuilder(Entity).');
} Type guard
function hasMainAlias(qb): boolean {
return !!qb.expressionMap.mainAlias;
} Prevention
- Prefer repo.relation(...) which binds the entity automatically.
- Never call .relation() on a builder without a FROM entity.
- Centralize relation operations in a service method that always starts from the repository.
When it happens
Trigger: You call dataSource.createQueryBuilder().relation(User, 'posts') without an entity/main alias, or call .relation() on a builder whose FROM was never set. relationMetadata runs before any relation lookup.
Common situations: Chaining .relation() on a fresh createQueryBuilder() with no entity. Constructing RelationQueryBuilder directly. Misusing the relation API on a subquery-based builder.
Related errors
- Relation ${this.relationPropertyPath} was not found in entit
- Cannot create relation id map for a single value because rel
- Cannot get entity metadata for the given alias "${this.name}
- Main alias is not set
- Cannot find alias for property ${propertyPath}
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/65b67e377487bb26.json.
Report an issue: GitHub.