{"record":{"id":"2c02265ec052c947","repo":"n8n-io/n8n","slug":"custom-entity-repository-repository-name-cannot","errorCode":null,"errorMessage":"Custom entity repository ${repository.name} cannot inherit Repository class without entity being set in the @EntityRepository decorator.","messagePattern":"Custom entity repository (.+?) cannot inherit Repository class without entity being set in the @EntityRepository decorator\\.","errorType":"exception","errorClass":"CustomRepositoryCannotInheritRepositoryError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/entity-manager/EntityManager.ts","lineNumber":1313,"sourceCode":"\t\t\t},\n\t\t);\n\t\tif (!entityRepositoryMetadataArgs) throw new CustomRepositoryNotFoundError(customRepository);\n\n\t\tconst entityMetadata = entityRepositoryMetadataArgs.entity\n\t\t\t? this.connection.getMetadata(entityRepositoryMetadataArgs.entity)\n\t\t\t: undefined;\n\t\tconst entityRepositoryInstance = new (entityRepositoryMetadataArgs.target as any)(\n\t\t\tthis,\n\t\t\tentityMetadata,\n\t\t);\n\n\t\t// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,\n\t\t// however we need these properties for internal work of the class\n\t\tif (entityRepositoryInstance instanceof AbstractRepository) {\n\t\t\tif (!(entityRepositoryInstance as any)['manager'])\n\t\t\t\t(entityRepositoryInstance as any)['manager'] = this;\n\t\t} else {\n\t\t\tif (!entityMetadata) throw new CustomRepositoryCannotInheritRepositoryError(customRepository);\n\t\t\t(entityRepositoryInstance as any)['manager'] = this;\n\t\t\t(entityRepositoryInstance as any)['metadata'] = entityMetadata;\n\t\t}\n\n\t\treturn entityRepositoryInstance;\n\t}\n\n\t/**\n\t * Releases all resources used by entity manager.\n\t * This is used when entity manager is created with a single query runner,\n\t * and this single query runner needs to be released after job with entity manager is done.\n\t */\n\tasync release(): Promise<void> {\n\t\tif (!this.queryRunner) throw new NoNeedToReleaseEntityManagerError();\n\n\t\treturn this.queryRunner.release();\n\t}\n}","sourceCodeStart":1295,"sourceCodeEnd":1331,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/entity-manager/EntityManager.ts#L1295-L1331","documentation":"In getCustomRepository, when the registered custom repository extends the plain Repository class (not AbstractRepository), TypeORM needs entity metadata to bind it. If the @EntityRepository decorator was applied without an entity argument (so entityRepositoryMetadataArgs.entity is undefined), and the class extends Repository, CustomRepositoryCannotInheritRepositoryError is thrown. AbstractRepository-based repos don't need an entity; Repository-based ones do.","triggerScenarios":"Writing `@EntityRepository()` (no entity) on a class that extends `Repository<T>`; refactoring from AbstractRepository to Repository but forgetting to add the entity to the decorator; using a bare @EntityRepository() on a generic Repository subclass for a multi-entity repo.","commonSituations":"Following a tutorial that used AbstractRepository then switching the base class; copy-paste where the entity argument was dropped; type confusion between Repository (entity-bound) and AbstractRepository (manager-bound).","solutions":["Pass the entity to the decorator: `@EntityRepository(User)` on Repository-extending classes.","If the repo intentionally serves multiple entities, extend `AbstractRepository` instead and use the injected `this.manager`.","Keep the rule of thumb: extends Repository<Entity> ⇒ @EntityRepository(Entity); extends AbstractRepository ⇒ @EntityRepository() is fine."],"exampleFix":"// before\n@EntityRepository()\nclass UserRepo extends Repository<User> { /* ... */ }\n\n// after - supply the entity\n@EntityRepository(User)\nclass UserRepo extends Repository<User> { /* ... */ }","handlingStrategy":"validation","validationCode":"import { getMetadataArgsStorage } from '@n8n/typeorm';\nimport { Repository, AbstractRepository } from '@n8n/typeorm';\nfunction assertRepoDecorationConsistent(repo: Function): void {\n  const meta = getMetadataArgsStorage().entityRepositories.find(r => r.target === repo);\n  if (!meta) throw new Error('missing @EntityRepository');\n  const extendsRepo = Object.prototype.isPrototypeOf.call(Repository.prototype, repo.prototype);\n  if (extendsRepo && !meta.entity) {\n    throw new Error(`${repo.name} extends Repository and must pass an entity to @EntityRepository`);\n  }\n}\nassertRepoDecorationConsistent(UserRepo);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Rule: extends Repository<Entity> ⇒ @EntityRepository(Entity).","Rule: extends AbstractRepository ⇒ @EntityRepository() is fine.","Audit decorator arguments when switching the base class.","Add a unit test that asserts every custom repo decoration is consistent."],"tags":["typeorm","custom-repository","decorators","api-misuse"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}