n8n-io/n8n · error · SubjectWithoutIdentifierError
Internal error. Subject ${subject.metadata.targetName} must
Error message
Internal error. Subject ${subject.metadata.targetName} must have an identifier to perform operation. What it means
Inside `executeUpdateOperations`, each update subject must carry an identifier (the primary-key map) so TypeORM can build `WHERE id = ...`. If `subject.identifier` is falsy it throws `SubjectWithoutIdentifierError`. The error's own docstring says this should never happen in normal use and is most likely an ORM-internal problem, but it surfaces when an update is attempted on an instance whose PK was never set.
Source
Thrown at packages/@n8n/typeorm/src/persistence/SubjectExecutor.ts:431
if (value !== undefined && value !== null) {
const preparedValue = this.queryRunner.connection.driver.prepareHydratedValue(
value,
column,
);
column.setEntityValue(subject.generatedMap!, preparedValue);
}
});
}
});
}
}
/**
* Updates all given subjects in the database.
*/
protected async executeUpdateOperations(): Promise<void> {
const updateSubject = async (subject: Subject) => {
if (!subject.identifier) throw new SubjectWithoutIdentifierError(subject);
const updateMap: ObjectLiteral = subject.createValueSetAndPopChangeMap();
// for tree tables we execute additional queries
switch (subject.metadata.treeType) {
case 'nested-set':
await new NestedSetSubjectExecutor(this.queryRunner).update(subject);
break;
case 'closure-table':
await new ClosureSubjectExecutor(this.queryRunner).update(subject);
break;
case 'materialized-path':
await new MaterializedPathSubjectExecutor(this.queryRunner).update(subject);
break;
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Ensure the entity instance has a non-null primary key before calling update/save (log `metadata.primaryColumns` values).
- Confirm the entity class declares a `@PrimaryGeneratedColumn()` / `@PrimaryColumn()`.
- If reached via cascade, reproduce with logging and report upstream — per the docs this path is considered an internal bug.
Example fix
// before — id cleared, then update
const u = await repo.findOneBy({ id: 1 });
u.id = undefined;
await repo.save(u); // throws inside executeUpdateOperations
// after — keep the identifier
const u = await repo.findOneBy({ id: 1 });
u.name = 'new';
await repo.save(u); Defensive patterns
Strategy: validation
Validate before calling
// Before update/save, confirm the instance carries a non-null primary key
function hasId<T>(entity: T, meta: EntityMetadata): boolean {
return meta.primaryColumns.every(c => c.getEntityValue(entity) != null);
}
if (!hasId(entity, dataSource.getMetadata(EntityClass))) {
throw new Error('Cannot update: entity has no identifier');
} Type guard
function hasPrimaryKey<T>(e: T, pk: keyof T): e is T & Record<typeof pk, NonNullable<T[typeof pk]>> {
return e != null && (e as any)[pk] != null;
} Try / catch
try { await repo.save(entity); } catch (e) { if (e instanceof SubjectWithoutIdentifierError) { /* log PK columns; reload entity before update */ } throw e; } Prevention
- Never null out a primary key on a tracked entity before save.
- Confirm every entity class declares a @PrimaryGeneratedColumn/@PrimaryColumn.
- Update entities you loaded from the DB, not freshly-constructed copies.
When it happens
Trigger: Calling `repository.update(entityInstance, ...)` or having cascade-update reach an entity instance whose primary key value is `undefined`/`null`. An entity with no `@PrimaryColumn`/`@PrimaryGeneratedColumn` being updated. Manually clearing the PK on a tracked entity before flush.
Common situations: Loading an entity, setting its id to undefined, then saving. A subclass/SINGLE_TABLE entity whose PK column isn't mapped. A bug in a custom subscriber that nulls the identifier.
Related errors
- Found unknown node. Make sure to provided all involved nodes
- Cannot update entity because entity id is not set in the ent
- Cannot ${operation}, given value must be instance of entity
- Removed entity "${subject.metadata.name}" is also scheduled
- Cyclic dependency: ${JSON.stringify(node)}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/9c16d70b9e360f49.
Report an issue: GitHub.