{"id":"65b67e377487bb26","repo":"typeorm/typeorm","slug":"entity-to-work-with-is-not-specified","errorCode":null,"errorMessage":"Entity to work with is not specified!","messagePattern":"Entity to work with is not specified!","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"src/query-builder/QueryExpressionMap.ts","lineNumber":465,"sourceCode":"        return alias\n    }\n\n    findColumnByAliasExpression(\n        aliasExpression: string,\n    ): ColumnMetadata | undefined {\n        const [aliasName, propertyPath] = aliasExpression.split(\".\")\n        const alias = this.findAliasByName(aliasName)\n        return alias.metadata.findColumnWithPropertyName(propertyPath)\n    }\n\n    /**\n     * Gets relation metadata of the relation this query builder works with.\n     *\n     * todo: add proper exceptions\n     */\n    get relationMetadata(): RelationMetadata {\n        if (!this.mainAlias)\n            throw new TypeORMError(`Entity to work with is not specified!`) // todo: better message\n\n        const relationMetadata =\n            this.mainAlias.metadata.findRelationWithPropertyPath(\n                this.relationPropertyPath,\n            )\n        if (!relationMetadata)\n            throw new TypeORMError(\n                `Relation ${this.relationPropertyPath} was not found in entity ${this.mainAlias.name}`,\n            ) // todo: better message\n\n        return relationMetadata\n    }\n\n    /**\n     * Copies all properties of the current QueryExpressionMap into a new one.\n     * Useful when QueryBuilder needs to create a copy of itself.\n     */\n    clone(): QueryExpressionMap {","sourceCodeStart":447,"sourceCodeEnd":483,"githubUrl":"https://github.com/typeorm/typeorm/blob/04ff4daedcf60fa4ffd0d5d33bbafaac1a9bbc96/src/query-builder/QueryExpressionMap.ts#L447-L483","documentation":"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.","triggerScenarios":"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.","commonSituations":"Chaining .relation() on a fresh createQueryBuilder() with no entity. Constructing RelationQueryBuilder directly. Misusing the relation API on a subquery-based builder.","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."],"exampleFix":"// before\nawait dataSource.createQueryBuilder()\n  .relation(User, 'posts').of(user).set(post); // 492\n\n// after\nawait dataSource.createQueryBuilder(User, 'user')\n  .relation(User, 'posts').of(user).set(post);\n// or simpler:\nawait repo.relation('posts').of(user).add(post);","handlingStrategy":"validation","validationCode":"function assertRelationBuilderHasMainAlias(qb) {\n  if (!qb.expressionMap.mainAlias) throw new Error('Relation ops require an entity main alias; use repo.relation() or createQueryBuilder(Entity).');\n}","typeGuard":"function hasMainAlias(qb): boolean {\n  return !!qb.expressionMap.mainAlias;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["relation","alias","entity","query-builder"],"analyzedSha":"04ff4daedcf60fa4ffd0d5d33bbafaac1a9bbc96","analyzedAt":"2026-08-03T18:27:32.281Z","schemaVersion":2}