n8n-io/n8n · error · CustomRepositoryNotFoundError
Custom repository ${repository.name} was not found. Did you
Error message
Custom repository ${repository.name} was not found. Did you forgot to put @EntityRepository decorator on it? What it means
EntityManager.getCustomRepository looks up the supplied custom repository class in the global metadata args storage (populated by the @EntityRepository decorator). If no matching target is found, it throws CustomRepositoryNotFoundError. The check matches on the constructor function itself, so passing an undecorated class or the wrong class (e.g. an instance) fails.
Source
Thrown at packages/@n8n/typeorm/src/entity-manager/EntityManager.ts:1297
}
/**
* Gets custom entity repository marked with @EntityRepository decorator.
*
* @deprecated use Repository.extend to create custom repositories
*/
getCustomRepository<T>(customRepository: ObjectType<T>): T {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.find(
(repository) => {
return (
repository.target ===
(typeof customRepository === 'function'
? customRepository
: (customRepository as any).constructor)
);
},
);
if (!entityRepositoryMetadataArgs) throw new CustomRepositoryNotFoundError(customRepository);
const entityMetadata = entityRepositoryMetadataArgs.entity
? this.connection.getMetadata(entityRepositoryMetadataArgs.entity)
: undefined;
const entityRepositoryInstance = new (entityRepositoryMetadataArgs.target as any)(
this,
entityMetadata,
);
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
// however we need these properties for internal work of the class
if (entityRepositoryInstance instanceof AbstractRepository) {
if (!(entityRepositoryInstance as any)['manager'])
(entityRepositoryInstance as any)['manager'] = this;
} else {
if (!entityMetadata) throw new CustomRepositoryCannotInheritRepositoryError(customRepository);
(entityRepositoryInstance as any)['manager'] = this;
(entityRepositoryInstance as any)['metadata'] = entityMetadata;View on GitHub (pinned to 5ac6606e81)
Solutions
- Decorate the custom repository with `@EntityRepository(MyEntity)` (and import it at least once so the decorator runs).
- Pass the class (constructor), not an instance: `getCustomRepository(UserRepo)` not `getCustomRepository(new UserRepo())`.
- Ensure your tsconfig has `experimentalDecorators: true` and `emitDecoratorMetadata: true`, and that the build pipeline preserves decorators.
- Break circular imports so the class registered equals the class referenced at the call site.
Example fix
// before
import { Repository } from '@n8n/typeorm';
class UserRepo extends Repository<User> { /* no decorator */ }
manager.getCustomRepository(UserRepo); // -> not found
// after
import { EntityRepository, Repository } from '@n8n/typeorm';
@EntityRepository(User)
class UserRepo extends Repository<User> {
findActive() { return this.find({ where: { active: true } }); }
}
manager.getCustomRepository(UserRepo); Defensive patterns
Strategy: validation
Validate before calling
import { getMetadataArgsStorage } from '@n8n/typeorm';
function isRegisteredCustomRepo(repo: Function): boolean {
return getMetadataArgsStorage().entityRepositories.some(r => r.target === repo);
}
if (!isRegisteredCustomRepo(UserRepo)) {
throw new Error('UserRepo missing @EntityRepository decorator');
}
await manager.getCustomRepository(UserRepo); Type guard
function isCustomRepoClass<T>(v: unknown): v is new (...args: any[]) => T {
return typeof v === 'function';
} Prevention
- Always decorate custom repos with @EntityRepository(Entity).
- Set experimentalDecorators and emitDecoratorMetadata in tsconfig.
- Pass the class, not an instance.
- Avoid circular imports so the registered class identity matches the call site.
When it happens
Trigger: Calling `manager.getCustomRepository(UserRepo)` on a class that lacks the `@EntityRepository(Entity)` decorator; passing an instance instead of the class; importing the wrong class with the same name from a different module; decorator metadata not emitted because emitDecoratorMetadata/decorators are off in tsconfig.
Common situations: Custom repo class never decorated; decorator stripped by build config (Babel/swc with decorators disabled); circular imports causing the class identity passed to differ from the registered one; TS + esbuild target mismatch where decorators don't survive transpilation.
Related errors
- Custom entity repository ${repository.name} cannot inherit R
- Invalid prefix option given for ${this.entityMetadata.target
- Column "${columnName}" was not found in table "${metadata.na
- Column ${propertyPath} was not found in ${metadata.targetNam
- ${select} column was not found in the ${metadata.name} entit
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/5cf321e0f3cb2eb0.
Report an issue: GitHub.