typeorm
>=0.3.0 <2.0.0postconditions39functions27last verified2026-06-23coverage score96%Postconditions: what we check
- find · find-query-errorerrorWhenquery fails (connection lost, invalid relation, timeout, syntax error)Throws
QueryFailedError or connection errorRequired handlingCaller MUST wrap repository.find() in try-catch to handle database errors. Connection failures and invalid queries crash application if unhandled.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - save · save-constraint-violationerrorWhensave violates constraint (unique, foreign key, validation, type mismatch)Throws
QueryFailedError with constraint violation detailsRequired handlingCaller MUST wrap save() in try-catch to handle constraint violations and validation errors. Unique violations, foreign key errors, and validation failures crash application if unhandled.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - transaction · transaction-errorerrorWhenoperation within transaction fails (constraint violation, deadlock, connection lost)Throws
Error causing automatic rollbackRequired handlingCaller MUST wrap transaction operations in try-catch to handle errors and ensure rollback. Unhandled errors leave database in inconsistent state if transaction partially commits.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[3] - findOne · findone-query-failed-errorerrorWhenDatabase query fails (connection lost, invalid relations, timeout)Throws
QueryFailedError (extends TypeORMError) with driverError containing underlying DB errorRequired handlingCaller MUST wrap in try-catch to handle database errors. findOne() returns null when not found — no need to handle EntityNotFoundError here. Distinguish null result (not found) from thrown error (DB failure) in caller logic.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - findOneBy · findoneby-query-failed-errorerrorWhenDatabase query fails (connection lost, invalid column, timeout)Throws
QueryFailedError with driverError containing underlying DB errorRequired handlingCaller MUST wrap in try-catch. A null return means not found (not an error). A thrown QueryFailedError means the DB operation failed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - findOneOrFail · findone-or-fail-entity-not-founderrorWhenNo entity matches the given find optionsThrows
EntityNotFoundError (extends TypeORMError) — message includes entity name and criteriaRequired handlingCaller MUST wrap in try-catch and handle EntityNotFoundError. Import EntityNotFoundError from 'typeorm' for type-safe instanceof checks. Distinguish from QueryFailedError (DB failure) vs EntityNotFoundError (not found). This is the GUARANTEED throw path — do not use findOneOrFail() without a catch block.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - findOneOrFail · findone-or-fail-query-failederrorWhenDatabase query fails (connection lost, timeout, invalid schema)Throws
QueryFailedError with driverError containing the underlying DB errorRequired handlingCaller MUST also handle QueryFailedError separately from EntityNotFoundError. Two distinct failure modes: entity not found vs DB failure.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - findOneByOrFail · findonebyorfail-entity-not-founderrorWhenNo entity matches the WHERE conditionsThrows
EntityNotFoundError (extends TypeORMError) — always thrown when no result foundRequired handlingCaller MUST wrap in try-catch. EntityNotFoundError has entityClass and criteria properties for context. This is the preferred pattern over findOneBy() + manual null check when entity MUST exist.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[6] - insert · insert-duplicate-key-errorerrorWhenUnique constraint or primary key violation (duplicate insert)Throws
QueryFailedError with driverError.code = 'ER_DUP_ENTRY' (MySQL), '23505' (PostgreSQL), 'SQLITE_CONSTRAINT' (SQLite)Required handlingCaller MUST wrap in try-catch. Check error.driverError.code for database-specific constraint violation codes. insert() is intentionally primitive — no upsert logic. Use upsert() for idempotent inserts. Unlike save(), insert() will not merge existing entities — always throws on duplicate PK.costmediumin prodimmediate exceptionusers seelost datavisibilityvisible - insert · insert-foreign-key-violationerrorWhenForeign key constraint violation (referenced entity does not exist)Throws
QueryFailedError with driverError containing FK violation detailsRequired handlingCaller MUST validate referenced entity existence before insert. Or wrap in try-catch and handle FK error from driverError.costmediumin prodimmediate exceptionusers seelost datavisibilityvisibleSources[4] - update · update-constraint-violationerrorWhenUpdate violates unique constraint or type mismatchThrows
QueryFailedError with driverError containing constraint violation detailsRequired handlingCaller MUST wrap in try-catch to handle constraint violations. Also check UpdateResult.affected to verify rows were actually updated — TypeORM does NOT throw if criteria match 0 rows.costmediumin prodimmediate exceptionusers seelost datavisibilityvisible - update · update-silent-no-opwarningWhenCriteria matches 0 rows — update silently affects nothingThrows
Does not throw — UpdateResult.affected === 0Required handlingCaller SHOULD check UpdateResult.affected after update(). If affected === 0, entity did not exist — decide whether to create or error. Typical bug: assume update succeeded without checking affected count.costmediumin prodsilent failureusers seedegraded performancevisibilitysilentSources[5] - delete · delete-foreign-key-constrainterrorWhenDelete violates foreign key constraint (other records reference this entity)Throws
QueryFailedError with driverError containing FK constraint detailsRequired handlingCaller MUST wrap in try-catch to handle FK constraint violations. Check driverError.code for database-specific FK codes (MySQL: ER_ROW_IS_REFERENCED_2, Postgres: 23503). Consider using cascade:true in entity relations or deleting dependent records first.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - delete · delete-silent-no-opwarningWhenCriteria matches 0 rows — delete silently affects nothingThrows
Does not throw — DeleteResult.affected === 0Required handlingCaller SHOULD check DeleteResult.affected after delete(). If business logic requires entity to exist, use findOneOrFail() first.costlowin prodsilent failureusers seedegraded performancevisibilitysilentSources[5] - upsert · upsert-constraint-violationerrorWhenForeign key violation or non-conflict unique constraint violated by upsertThrows
QueryFailedError with driverError containing constraint violation detailsRequired handlingCaller MUST wrap in try-catch. Conflict resolution only handles the specified conflictPaths — other constraints still throw. Check driverError.code for database-specific constraint codes.costmediumin prodimmediate exceptionusers seelost datavisibilityvisible - query · query-sql-syntax-errorerrorWhenSQL query has syntax error or references non-existent table/columnThrows
QueryFailedError with driverError containing the SQL error details and the original queryRequired handlingCaller MUST wrap in try-catch. QueryFailedError.query contains the SQL that failed — useful for debugging. QueryFailedError.driverError contains database-specific error code and message.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - query · query-sql-injection-riskerrorWhenUser input interpolated directly into SQL string (not using parameterized query)Throws
Does not throw — silently allows SQL injectionRequired handlingALWAYS use parameterized queries: repository.query('SELECT * FROM users WHERE id = $1', [userId]) NEVER concatenate user input into SQL: repository.query(`SELECT * FROM users WHERE id = ${userId}`) SQL injection can exfiltrate entire database or destroy all data.costhighin prodsilent failureusers seesecurity breachvisibilitysilentSources[5] - softDelete · softdelete-missing-delete-date-columnerrorWhenEntity does not have a @DeleteDateColumn() decorated fieldThrows
MissingDeleteDateColumnError (extends TypeORMError) — entity name included in messageRequired handlingEnsure entity class has @DeleteDateColumn() column before calling softDelete(). Add column: @DeleteDateColumn() deletedAt: Date This error occurs at runtime — schema mismatch between entity definition and usage.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - softDelete · softdelete-silent-no-opwarningWhenCriteria matches 0 rows — softDelete silently affects nothingThrows
Does not throw — UpdateResult.affected === 0Required handlingCheck UpdateResult.affected to verify rows were actually soft-deleted.costlowin prodsilent failureusers seedegraded performancevisibilitysilentSources[5] - restore · restore-missing-delete-date-columnerrorWhenEntity does not have @DeleteDateColumn() decorated fieldThrows
MissingDeleteDateColumnError (extends TypeORMError)Required handlingEnsure entity has @DeleteDateColumn() before calling restore(). Same configuration requirement as softDelete().costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - remove · remove-foreign-key-constrainterrorWhenFK constraint violation on entity or cascaded entitiesThrows
QueryFailedError with driverError containing FK constraint detailsRequired handlingCaller MUST wrap in try-catch. Unlike delete(), remove() processes relations — cascade errors surface here. Ensure all dependent records are handled (deleted or reassigned) before removing.costmediumin prodimmediate exceptionusers seelost datavisibilityvisibleSources[4] - count · count-query-failed-errorerrorWhenDatabase query fails (connection lost, invalid relations, timeout)Throws
QueryFailedError with driverError containing the database errorRequired handlingCaller MUST wrap in try-catch. Pagination logic that depends on count() can expose incorrect totals if errors are swallowed.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - findBy · findby-query-failed-errorerrorWhenDatabase query fails (connection lost, invalid column, timeout)Throws
QueryFailedError with driverErrorRequired handlingCaller MUST wrap in try-catch. Empty array is a valid result — not an error.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - findAndCount · findandcount-query-failed-errorerrorWhenEither the find or count query fails (connection lost, timeout)Throws
QueryFailedError with driverErrorRequired handlingCaller MUST wrap in try-catch. A failed findAndCount() leaves pagination state undefined — do not cache partial results. Common pagination pattern: never silently fall back to page 1 on error.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - increment · increment-type-mismatcherrorWhenColumn is not numeric or propertyPath does not exist on entityThrows
QueryFailedError or TypeORMError with type mismatch detailsRequired handlingCaller MUST wrap in try-catch. Ensure propertyPath is a numeric @Column — calling increment() on a string column throws at runtime. Also check UpdateResult.affected — silent no-op if criteria matches 0 rows.costlowin prodimmediate exceptionusers seelost datavisibilityvisible - decrement · decrement-type-mismatcherrorWhenColumn is not numeric, propertyPath does not exist, or check constraint violatedThrows
QueryFailedError or TypeORMErrorRequired handlingCaller MUST wrap in try-catch. Database-level check constraints (e.g., balance >= 0) will throw QueryFailedError on violation. Application-level guard: ensure value is > 0 before decrementing counters/balances.costlowin prodimmediate exceptionusers seelost datavisibilityvisibleSources[4] - initialize · initialize-already-connectederrorWhenDataSource.initialize() called when DataSource is already initialized (isInitialized === true)Throws
CannotConnectAlreadyConnectedError (extends TypeORMError)Required handlingCheck dataSource.isInitialized before calling initialize(). Or guard with: if (!dataSource.isInitialized) await dataSource.initialize() Common bug: initializing inside request handlers (called on every request).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - initialize · initialize-connection-failureerrorWhenCannot connect to database (wrong credentials, host unreachable, invalid connection string)Throws
Error from underlying database driver (propagated through DataSource, destroys partial state)Required handlingCaller MUST wrap in try-catch and handle startup failure gracefully. A failed initialize() should stop application startup — log error and exit. Re-throwing is acceptable at startup boundary; silently swallowing means no DB access but no visible error.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - destroy · destroy-not-initializedwarningWhenDataSource.destroy() called when DataSource is not initializedThrows
CannotExecuteNotConnectedError (extends TypeORMError)Required handlingCheck dataSource.isInitialized before calling destroy(). Pattern: if (dataSource.isInitialized) await dataSource.destroy() Common in test teardown or graceful shutdown handlers.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - synchronize · synchronize-query-failed-errorerrorWhenDDL execution fails (schema lock, permission denied, conflicting constraints)Throws
QueryFailedError with driverError containing the DDL errorRequired handlingCaller MUST wrap in try-catch. synchronize() runs many DDL statements — partial failure leaves schema half-migrated. DO NOT call synchronize() in production code paths. Use migrations instead. Common bug: synchronize: true in DataSource config silently corrupts production schema.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - synchronize · synchronize-not-connectederrorWhensynchronize() called on DataSource that is not yet initializedThrows
CannotExecuteNotConnectedError (extends TypeORMError)Required handlingEnsure dataSource.initialize() has been awaited before calling synchronize(). Pattern: await dataSource.initialize(); await dataSource.synchronize().costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[12] - runMigrations · run-migrations-query-failed-errorerrorWhenA migration fails mid-execution (DDL error, constraint violation, data conversion failure)Throws
QueryFailedError with driverError containing the failing SQL and database errorRequired handlingCaller MUST wrap in try-catch and stop application startup on failure. With transaction:"each" (default) the failing migration rolls back, but earlier migrations in the batch have already committed — the schema is in a partially-migrated state. Pattern: on failure, log error, exit non-zero; do NOT proceed to serve traffic with a half-migrated schema. Re-running runMigrations() after a fix is safe.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - runMigrations · run-migrations-not-connectederrorWhenrunMigrations() called before dataSource.initialize() has resolvedThrows
CannotExecuteNotConnectedError (extends TypeORMError)Required handlingAlways await dataSource.initialize() before runMigrations(). Pattern: await dataSource.initialize(); await dataSource.runMigrations().costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[12] - startTransaction · start-transaction-already-startederrorWhenstartTransaction() called when QueryRunner already has an active transactionThrows
TransactionAlreadyStartedError (extends TypeORMError)Required handlingCheck queryRunner.isTransactionActive before calling startTransaction(). Common bug: calling startTransaction() twice in nested service methods on the same runner. Nested transactions need savepoints, not a second startTransaction() call.costmediumin prodimmediate exceptionusers seelost datavisibilityvisible - startTransaction · start-transaction-already-releasederrorWhenstartTransaction() called on a QueryRunner that has already been releasedThrows
QueryRunnerAlreadyReleasedError (extends TypeORMError)Required handlingAcquire a fresh QueryRunner via dataSource.createQueryRunner() for each transaction. Do NOT reuse a runner after calling release() — it cannot run further queries. Pattern: const qr = ds.createQueryRunner(); try { await qr.startTransaction(); ... } finally { await qr.release(); }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[17] - commitTransaction · commit-transaction-not-startederrorWhencommitTransaction() called when no transaction is active on the QueryRunnerThrows
TransactionNotStartedError (extends TypeORMError)Required handlingCheck queryRunner.isTransactionActive before commit. Common bug: calling commitTransaction() in a finally block when an early error prevented startTransaction() from running. Pattern: if (queryRunner.isTransactionActive) await queryRunner.commitTransaction().costmediumin prodimmediate exceptionusers seelost datavisibilityvisible - commitTransaction · commit-transaction-query-failederrorWhenUnderlying COMMIT SQL fails (deadlock, serialization failure, connection lost)Throws
QueryFailedError with driverError (e.g. Postgres 40001 serialization_failure, 40P01 deadlock_detected)Required handlingCaller MUST wrap commit in try-catch AND rollback on failure. A failed commit means the transaction may be in an indeterminate state — the safe path is rollbackTransaction() then release(), and surface the error to the caller. Retry policy for serialization/deadlock errors lives at the caller layer, not here.costmediumin prodimmediate exceptionusers seelost datavisibilityvisibleSources[4] - release · release-already-releasedwarningWhenrelease() called on a QueryRunner that has already been releasedThrows
QueryRunnerAlreadyReleasedError (extends TypeORMError)Required handlingRelease the runner exactly once, in a finally block at the end of its scope. Common bug: double-release when error handling code calls release() AND a finally block also calls release(). Pattern: const qr = ds.createQueryRunner(); try { ... } finally { await qr.release(); }costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisibleSources[17] - release · release-not-called-connection-leakerrorWhenQueryRunner created via createQueryRunner() but release() never calledThrows
Does not throw — silent connection pool exhaustionRequired handlingALWAYS call queryRunner.release() in a finally block. Forgetting release() under error paths is the dominant cause of TypeORM connection pool exhaustion (DataSource hangs on next query waiting for a free connection). Pattern: const qr = ds.createQueryRunner(); try { ... } finally { await qr.release(); }. Never put logic between createQueryRunner() and the try block.costhighin prodsilent failureusers seeservice unavailablevisibilitysilent
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]typeorm.io/find-optionsFind Options
- [2]typeorm.io/repository-apiRepository Api
- [3]typeorm.io/transactionsTransactions
- [5]typeorm.io/docs/working-with-entity-manager/repository-apiRepository Api
- [11]typeorm.io/docs/data-source/data-source-apiData Source Api
- [13]typeorm.io/data-source-optionsData Source Options
- [15]typeorm.io/migrationsMigrations
- [19]typeorm.io/data-source-apiData Source Api
- [20]typeorm.io/query-runnerQuery Runner
- [4]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · QueryFailedError.ts
- [6]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · EntityNotFoundError.ts
- [7]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · EntityManager.ts
- [8]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · MissingDeleteDateColumnError.ts
- [9]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · DataSource.ts
- [10]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · CannotConnectAlreadyConnectedError.ts
- [12]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · CannotExecuteNotConnectedError.ts
- [14]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · MigrationExecutor.ts
- [16]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · TransactionAlreadyStartedError.ts
- [17]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · QueryRunnerAlreadyReleasedError.ts
- [18]raw.githubusercontent.com/typeorm/typeorm/mastertypeorm/typeorm · TransactionNotStartedError.ts
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources: typeorm
Package: typeorm
Version: 0.3.x
Category: database (TypeScript ORM)
Status: ✅ Complete
Official Documentation
- Main Docs: https://typeorm.io/
- Repository API: https://typeorm.io/repository-api
- Transactions: https://typeorm.io/transactions
- Data Source: https://typeorm.io/data-source
- npm: https://www.npmjs.com/package/typeorm
Behavioral Requirements
Database Errors: Connection failures, constraint violations, query errors Must wrap repository operations in try-catch Transactions must handle errors to ensure rollback DataSource must be initialized before use DataSource must be destroyed on shutdown
Contract Rationale
Repository operations can fail: Validation, constraints, connections Transaction errors leave inconsistent state: Must rollback Uninitialized DataSource causes crashes Unclosed connections prevent shutdown
Created: 2026-02-26 Status: ✅ COMPLETE