ErrLookup › Background articles › TypeORMError explained: why TypeORM throws its base error class for bad decorators, where filters, and schema mismatches
TypeORMError explained: why TypeORM throws its base error class for bad decorators, where filters, and schema mismatches
TypeORMError is the base error class TypeORM throws for configuration defects, unsafe query inputs, and schema-guard failures before any SQL reaches the database. Developers meet it as 'Undefined value encountered in property...' in find() filters, 'Dependency Cycle Found' at startup, 'was not found in table...' during migrations, and dozens of similar guard messages. This family covers the 334 documented TypeORMError records across the typeorm and n8n repositories and explains the shared mechanism behind them.
Distilled from 334 documented records across 2 repositories.
Background
TypeORMError is TypeORM's own base error class, thrown by the framework itself rather than surfaced from the database driver. It appears across three layers of the stack: metadata validation at DataSource startup, query building before SQL is emitted, and schema synchronization or migration execution. Because it is a guard, almost every TypeORMError means TypeORM refused to do something that would otherwise produce a wrong result or invalid SQL — it is a fail-fast boundary, not a downstream database failure.
The class does two broad jobs. First, it protects query semantics: the where-criteria normalizer throws on null and undefined values in where objects because those would otherwise be dropped or silently expanded into column = NULL, yielding broader result sets than the caller intended. Second, it validates configuration and schema state: the metadata builder throws when a relation target is unregistered, a join column references a nonexistent property, an index points at a non-column, or a cycle of non-nullable join columns would make inserts impossible. Both jobs share the same shape — name the offending property, table, or value, and stop before damage is done.
From the caller's side, the lifecycle position tells you which subsystem to blame. Errors at startup (dependency cycles, missing entity metadata, SQLite composite autoincrement, abstract-driver misuse) come from metadata building during DataSource initialization. Errors at query time (where value guards, empty write criteria, query-builder alias misuse, aggregate column lookup) come from query construction. Errors during synchronize or migrations (constraint, view, and column not found in the cache; JSON default comparison failures) come from schema comparison against TypeORM's in-memory table/view cache rather than the live database.
The family spans two repositories because n8n bundles TypeORM as its persistence layer. n8n's TypeORMError records — aggregate column lookup, entity metadata resolution, index and referenced-column building — are the same machinery invoked from n8n's own entity usage; nothing about them is n8n-specific. Where individual messages differ in wording or trigger conditions, the behavior is library-version-specific rather than a divergence in mechanism.
Common causes
- null or undefined values in where conditions.The default invalidWhereValuesBehavior is 'throw', so passing { where: { deletedAt: null } } or leaving an optional filter undefined fires 'Null value encountered' or 'Undefined value encountered' before the query runs. TypeORM refuses to guess because null has SQL IS NULL semantics and undefined would be silently dropped, widening the result set.
- Relation, join-column, and index decorator misconfiguration.The metadata builder throws when a @ManyToOne targets an unregistered entity, a @JoinTable/@JoinColumn references a property that does not exist, an @Index points at a non-column, or two entities form a cycle of non-nullable join columns. These surface at DataSource initialization or at the first query that touches the relation.
- Schema-cache mismatch during migrations and sync.dropCheckConstraint, dropView, and renameColumn resolve objects against TypeORM's in-memory schema cache, not the live database. A constraint renamed out-of-band, a view never loaded, or a column already dropped causes 'was not found' guards to fire even when the migration logic is otherwise correct.
- Unsupported or unrecognized transaction isolation levels.Each driver advertises only a subset of TypeORM's isolation levels. Passing SNAPSHOT to MySQL, a typo like READ_COMMITED, or a value outside the supported set triggers 'isolation level is not supported' at startTransaction or during the SQL Server parseIsolationLevel switch.
- QueryBuilder relation-API and alias misuse.The single-argument relation(prop) form sets no main alias, so a following .of().set() throws 'Entity to work with is not specified'. loadRelationIdAndMap requires an alias.property string and rejects extra conditions on ManyToOne and OneToOne-owner relations; many-to-many joins must go through the relation path, not the junction table name.
- Driver-capability assumptions.Some guards reject feature requests a driver cannot satisfy: a typed @Index on a driver without supportedIndexTypes, AUTOINCREMENT on a composite SQLite primary key, cascade:true on MongoDB clearTable, or instantiating the abstract AbstractSqliteDriver base instead of a concrete sqlite driver.
- Malformed JSON default values during schema comparison.On SQLite and Postgres, compareJsonDefaults runs JSON.parse on json/jsonb column defaults during synchronize. A SyntaxError is expected and ignored, but any other parse failure (TypeError, RangeError) is rewrapped as 'Failed to compare default values' and aborts the sync.
- Missing primary key on updated entities.On drivers without RETURNING (MySQL, SQLite), the returning-results updator re-selects the updated row by its id; if the entity instance carries no primary-key value it throws 'Cannot update entity because entity id is not set' rather than issue an unscoped SELECT.
What usually fixes it
- Express SQL NULL with IsNull() and strip undefined or empty keys from where objects before querying; for pervasive dynamic filters set invalidWhereValuesBehavior to 'ignore' or 'sql-null' in DataSource options.
- Register every entity and relation target in the DataSource entities array, make at least one side of any bidirectional join-column relation nullable, and verify referencedColumnName and @Index column arrays against real @Column property names — never DB column names.
- Pass ifExists:true to dropCheckConstraint and dropView, order migrations so creates run before drops, and refresh the schema cache (reconnect or synchronize) after any out-of-band schema change so the in-memory Table matches the live database.
- Read dataSource.driver.supportedIsolationLevels at startup and restrict isolation level strings to the supported union; default to READ COMMITTED for cross-engine portability.
- Use the two-argument relation(Entity, prop) form or Repository.relation, join many-to-many relations through alias.relation paths instead of junction table names, and reserve loadRelationIdAndMap condition callbacks for ManyToMany and inverse OneToOne.
- Avoid synchronize:true in production in favor of explicit migrations; for json/jsonb columns use function-based defaults so the comparison path is not hit, and keep defaults as valid JSON in both the database and entity metadata.
Documented occurrences
- Unknown isolation level "${isolation}"(typeorm/typeorm)
- Dependency Cycle Found: ${currentPath.join(" -> ")}(typeorm/typeorm)
- File ${fileNameOrLocalStorageOrData} does not exist(typeorm/typeorm)
- Supplied check constraint was not found in table ${table.name}(typeorm/typeorm)
- Column "${column.propertyPath}" is missing a referencedColumn in junction table "${junctionMetadata.tableName}".(typeorm/typeorm)
- Failed to compare default values of ${columnMetadata.propertyName} column(typeorm/typeorm)
- Cannot update entity because entity id is not set in the entity.(typeorm/typeorm)
- Additional condition can not be used with ManyToOne or OneToOne owner relations.(typeorm/typeorm)
- Column "${columnName}" was not found in table "${metadata.name}"(n8n-io/n8n)
- Sqlite does not support AUTOINCREMENT on composite primary key(typeorm/typeorm)
- Failed to compare default values of ${columnMetadata.propertyName} column(typeorm/typeorm)
- Given value must be a string representation of alias property(typeorm/typeorm)
- Entity to work with is not specified!(typeorm/typeorm)
- Null value encountered in property '${propertyPath}' of a where condition. To match with SQL NULL, the IsNull() operator must be used. Set 'invalidWhereValuesBehavior.null' to 'ignore' or 'sql-null' in connection options to skip or handle null values.(typeorm/typeorm)
- ${isolationLevel} isolation level is not supported(typeorm/typeorm)
- Undefined value encountered in property '${propertyPath}' of a where condition. Set 'invalidWhereValuesBehavior.undefined' to 'ignore' in connection options to skip properties with undefined values.(typeorm/typeorm)
- Do not use AbstractSqlite directly, it has to be used with one of the sqlite drivers(typeorm/typeorm)
- Relation ${this.relationPropertyPath} was not found in entity ${this.mainAlias.name}(typeorm/typeorm)
- Supported only in tree entities(typeorm/typeorm)
- View "${viewName}" does not exist.(typeorm/typeorm)
…and 314 more across the corpus — use search.
Honest provenance: generated on 2026-08-12 from AI-assisted analysis of the linked records. See how records are made.