typeorm/typeorm · error · CannotDetermineEntityError
Cannot ${operation}, given value must be instance of entity
Error message
Cannot ${operation}, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call. What it means
Thrown as `CannotDetermineEntityError` inside `EntityPersistExecutor.execute()` when the entity target cannot be inferred: the passed value is a plain object literal whose `constructor === Object`, and no explicit `target` (entity class) was supplied to the persist call. TypeORM needs an entity class to look up metadata; without it, save/remove/etc. is refused.
Source
Thrown at src/persistence/EntityPersistExecutor.ts:79
try {
// collect all operate subjects
const entities: ObjectLiteral[] = Array.isArray(this.entity)
? this.entity
: [this.entity]
const chunkSize = this.options?.chunk ?? 0
const entitiesInChunks =
chunkSize > 0 ? OrmUtils.chunk(entities, chunkSize) : [entities]
const buildExecutor = async (
entities: ObjectLiteral[],
): Promise<SubjectExecutor> => {
const subjects: Subject[] = []
// create subjects for all entities we received for the persistence
entities.forEach((entity) => {
const entityTarget = this.target ?? entity.constructor
if (entityTarget === Object)
throw new CannotDetermineEntityError(this.mode)
const metadata = this.dataSource
.getMetadata(entityTarget)
.findInheritanceMetadata(entity)
subjects.push(
new Subject({
metadata,
entity: entity,
canBeInserted: this.mode === "save",
canBeUpdated: this.mode === "save",
mustBeRemoved: this.mode === "remove",
canBeSoftRemoved: this.mode === "soft-remove",
canBeRecovered: this.mode === "recover",
}),
)
})
View on GitHub (pinned to 04ff4daedc)
Solutions
- Construct an entity instance before saving: `manager.save(Object.assign(new User(), dto))`.
- Pass the entity target explicitly as the first argument: `manager.save(User, dto)` or `manager.save(User, [dto1, dto2])`.
- When using a repository, ensure the values retain their class prototype (avoid `JSON.parse` / spread that produces plain objects).
Example fix
// before
await dataSource.manager.save({ name: "Alex", email: "a@b.c" })
// after — pass the target explicitly
await dataSource.manager.save(User, { name: "Alex", email: "a@b.c" })
// or construct an instance
const u = Object.assign(new User(), { name: "Alex", email: "a@b.c" })
await dataSource.manager.save(u) Defensive patterns
Strategy: type-guard
Validate before calling
// Reject plain object literals before persistence
function assertEntityInstance(value: any, target?: Function): void {
if (!target && value?.constructor === Object) {
throw new Error("Refusing to persist a plain object literal; pass a target or an instance")
}
} Type guard
function isEntityInstance<T>(value: any, target: new () => T): value is T {
return value instanceof target
} Try / catch
try {
await manager.save(value)
} catch (e) {
if (e instanceof CannotDetermineEntityError) {
await manager.save(Target, value) // retry with explicit target
} else throw e
} Prevention
- Always construct entity instances (`new User()`) rather than passing plain objects from req.body.
- When using DTOs, map them onto instances via `Object.assign(new User(), dto)` or a mapper.
- Prefer the repository API (`userRepo.save(...))`, which binds the target automatically.
When it happens
Trigger: `dataSource.manager.save({ name: "x" })` with a plain object and no class; `repository.save([{ id: 1 }])` where elements are object literals; calling `entityManager.persist(target=undefined, plainObject)`; spreading a class instance into a plain object (`{ ...user }`) before saving.
Common situations: Refactoring from class instances to plain DTOs; passing parsed JSON bodies directly to save; using `Object.assign({}, entity)` which strips the prototype; mixing repository-style (`repo.save(plainObj)`) with entityManager-style without a target.
Related errors
- File "${fullPath}.ts" already exists
- MongoEntityManager is only available for MongoDB databases.
- SqljsEntityManager is only available for Sqljs databases.
- No location is set, specify a location parameter or add the
- Could not save database, error: ${e}
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/f73a514a896ac83e.json.
Report an issue: GitHub.