knex
>=3.0.0 <4.0.0postconditions36functions24last verified2026-06-23coverage score100%Postconditions: what we check
- select · select-query-errorerrorWhenquery fails (syntax error, connection lost, timeout, invalid table/column)Throws
Error with query details and database-specific error codeRequired handlingCaller MUST wrap select() in try-catch to handle SQL errors, connection failures, and timeouts. Query errors crash application if unhandled.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - insert · insert-constraint-violationerrorWheninsert violates constraint (unique, foreign key, not null, type mismatch)Throws
Error with constraint violation details and database error codeRequired handlingCaller MUST wrap insert() in try-catch to handle constraint violations. Unique violations, foreign key errors, and type mismatches crash application if unhandled.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - update · update-no-try-catcherrorWhenupdate() called in async context without try-catch or .catch() handlerThrows
Error with database-specific error code and query detailsRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[3] - update · update-zero-rows-not-checkedwarningWhenupdate() result (number of affected rows) is not checked after execution — caller assumes update succeeded when WHERE matched nothingThrows
does not throw — returns 0 silentlyRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[3] - delete · delete-no-try-catcherrorWhendel()/delete() called in async context without try-catch or .catch() handlerThrows
Error with database-specific error code; KnexTimeoutError on connection timeoutRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - delete · delete-foreign-key-violationerrorWhendelete() called on a parent row that has child rows in another table with a foreign key constraint, without CASCADEThrows
Error with foreign key constraint violation from database driverRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - first · first-no-try-catcherrorWhenfirst() called in async context without try-catchThrows
Error with database-specific error code on query failureRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[5] - first · first-undefined-not-checkederrorWhenfirst() result used directly without null/undefined check before accessing properties (e.g. result.id, result.name)Throws
TypeError: Cannot read properties of undefined at runtimeRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[5] - raw · raw-no-try-catcherrorWhenknex.raw() called in async context without try-catchThrows
Error with SQL error details from database; or binding Error synchronously on undefined bindingRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[6] - raw · raw-sql-injection-riskerrorWhenknex.raw() called with user-provided input interpolated directly into the SQL string (template literal or string concatenation) instead of using binding parametersThrows
does not throw — silently executes malicious SQLRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[7] - destroy · destroy-not-called-on-shutdownwarningWhenknex instance is created but destroy() is never called — process exits (or tries to exit) without closing the connection poolThrows
does not throw — process hangs indefinitely, never exitsRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - destroy · destroy-no-try-catchwarningWhenawait knex.destroy() called without try-catchThrows
Error on pool teardown failure (rare but possible on network error)Required handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - batchInsert · batch-insert-no-try-catcherrorWhenbatchInsert() called without try-catch around the awaitThrows
Error on constraint violation or connection failure (same as insert()); TypeError for invalid chunkSize or non-array batch inputRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[9] - migrate.latest · migrate-latest-no-try-catcherrorWhenawait knex.migrate.latest() called without try-catch in server startup or deployment scriptsThrows
LockError if migration table is already locked by another process; Error from migration scripts that throw; KnexTimeoutError on database connection failureRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - migrate.latest · migrate-latest-lock-not-released-on-crasherrorWhenProcess crashes during migrate.latest() execution (SIGKILL, OOM, power failure) leaving migration lock in locked stateThrows
LockError('Migration table is already locked') on all subsequent migrate.latest() callsRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - migrate.rollback · migrate-rollback-no-try-catcherrorWhenawait knex.migrate.rollback() called without try-catchThrows
LockError if migration table is already locked; Error from down() migration scripts that throw; Error if named migration not foundRequired handlingCaller MUST handle this condition appropriately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - transaction · transaction-errorerrorWhenquery within transaction fails (constraint violation, deadlock, connection lost)Throws
Error causing automatic rollback if unhandledRequired handlingCaller MUST wrap transaction callback in try-catch to handle errors and ensure proper rollback. Unhandled errors may leave database in inconsistent state if transaction partially commits.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[11] - increment · increment-no-try-catcherrorWhenincrement() called in async context without try-catch or .catch() handlerThrows
Error with database-specific error code on connection failure, invalid column name, or type mismatch (e.g. incrementing a non-numeric column); KnexTimeoutError after acquireConnectionTimeout on pool exhaustionRequired handlingCaller MUST wrap await knex(table).where({...}).increment() in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - increment · increment-zero-rows-not-checkedwarningWhenincrement() result (number of affected rows) is not checked after execution — caller assumes counter was incremented when WHERE matched nothing (row does not exist)Throws
does not throw — returns 0 silentlyRequired handlingCaller SHOULD check the return value of increment(). If the returned count is 0, either the WHERE condition matched nothing or the row was deleted. For counter semantics that require the row to exist, verify count > 0 or use an upsert pattern.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - decrement · decrement-no-try-catcherrorWhendecrement() called in async context without try-catch or .catch() handlerThrows
Error with database-specific error code on connection failure, invalid column name, or type mismatch; KnexTimeoutError on pool exhaustionRequired handlingCaller MUST wrap await knex(table).where({...}).decrement() in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - decrement · decrement-zero-rows-not-checkedwarningWhendecrement() result (number of affected rows) is not checked after execution — caller assumes counter was decremented when WHERE matched nothingThrows
does not throw — returns 0 silentlyRequired handlingCaller SHOULD check the returned row count. If 0, the target row was not found. For inventory/seat management, treat 0-row decrement as a precondition failure.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - transactionProvider · transaction-provider-factory-no-try-catcherrorWhenawait trxProvider() called without try-catch around the factory invocationThrows
KnexTimeoutError if connection pool is exhausted when the factory is first called; Error on any database-level failure during transaction initializationRequired handlingCaller MUST wrap await trxProvider() in try-catch, especially in high-concurrency contexts where connection pool exhaustion is possible.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transactionProvider · transaction-provider-connection-not-releasederrorWhenFactory invocation succeeds but neither trx.commit() nor trx.rollback() is ever called — transaction is left open indefinitelyThrows
does not throw — connection silently hangsRequired handlingMUST ensure trx.commit() or trx.rollback() is called in all code paths. Use try/finally: const trx = await trxProvider(); try { ...; await trx.commit(); } catch (err) { await trx.rollback(err); throw err; }costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - schema.createTable · schema-create-table-no-try-catcherrorWhenawait knex.schema.createTable(...) called without try-catchThrows
Error if table already exists (database-native: "relation already exists" in PostgreSQL, "Table already exists" in MySQL/SQLite); Error if the connected user lacks CREATE TABLE privileges; KnexTimeoutError on connection pool exhaustion during DDLRequired handlingCaller MUST wrap await knex.schema.createTable() in try-catch in migration scripts. In deployment automation, check for "already exists" errors to handle idempotent re-deployments. Use knex migration system (migrate.latest) rather than manually calling createTable() for idempotent DDL management.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - schema.dropTable · schema-drop-table-no-try-catcherrorWhenawait knex.schema.dropTable(...) called without try-catchThrows
Error if table does not exist ("relation does not exist" in PostgreSQL, "Unknown table" in MySQL); Error if FK constraints reference the table from another table without CASCADE ("cannot drop table X because other objects depend on it" in PostgreSQL); Error if user lacks DROP privilege; KnexTimeoutError on pool exhaustionRequired handlingCaller MUST wrap await knex.schema.dropTable() in try-catch. Prefer dropTableIfExists() for idempotent down() migrations to avoid the "does-not-exist" error on re-runs.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[16] - schema.alterTable · schema-alter-table-no-try-catcherrorWhenawait knex.schema.alterTable(...) called without try-catchThrows
Error on type-incompatible conversions ("cannot cast type X to type Y" in PostgreSQL, "Incorrect integer value" in MySQL); Error when ADD COLUMN NOT NULL without default is applied to a non-empty table ("column contains null values"); Error on lock timeout when another transaction holds a conflicting lock on the target table (PostgreSQL lock_timeout setting, MySQL lock_wait_timeout); Error on duplicate column name when ADD COLUMN targets an existing column; KnexTimeoutError on pool exhaustionRequired handlingCaller MUST wrap await knex.schema.alterTable() in try-catch. For production deploys against a live table, set a lock_timeout (PostgreSQL) or innodb_lock_wait_timeout (MySQL) and handle the timeout error explicitly rather than blocking writes indefinitely.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[16] - schema.hasTable · schema-has-table-no-try-catchwarningWhenawait knex.schema.hasTable(...) called without try-catchThrows
KnexTimeoutError on connection pool exhaustion (60s default); Error on connection failure to the database; Error on permission denied if the connected user lacks SELECT on the system catalogRequired handlingCaller MUST wrap await knex.schema.hasTable() in try-catch in bootstrap and migration code. Treat connection failures as a startup error and surface them before the app starts accepting traffic.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[16] - schema.hasColumn · schema-has-column-no-try-catchwarningWhenawait knex.schema.hasColumn(...) called without try-catchThrows
KnexTimeoutError on pool exhaustion; Error on connection failure; Error on permission denied against the system catalogRequired handlingCaller MUST wrap await knex.schema.hasColumn() in try-catch in migration guard-code.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[16] - migrate.up · migrate-up-no-try-catcherrorWhenawait knex.migrate.up(...) called without try-catchThrows
LockError("Migration table is already locked") if another process holds the lock; Error from the migration script's up() function; Error("Migration X was not found") if config.name references a missing migration; KnexTimeoutError on connection pool exhaustionRequired handlingCaller MUST wrap await knex.migrate.up() in try-catch in deploy scripts. Distinguish LockError (concurrent deploy — retry/wait) from script errors (genuine migration failure — alert and rollback).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - migrate.down · migrate-down-no-try-catcherrorWhenawait knex.migrate.down(...) called without try-catchThrows
LockError("Migration table is already locked"); Error from the migration script's down() function; Error("Migration X was not run") if the specified name refers to a migration that was never applied; KnexTimeoutError on pool exhaustionRequired handlingCaller MUST wrap await knex.migrate.down() in try-catch. In rollback automation, surface the underlying script error rather than retrying — a failing down() step usually indicates the migration's down() logic is broken or the data has drifted.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - migrate.forceFreeMigrationsLock · migrate-force-free-lock-no-try-catchwarningWhenawait knex.migrate.forceFreeMigrationsLock(...) called without try-catchThrows
Error on UPDATE failure against the lock table; KnexTimeoutError on pool exhaustion; Error on permission denied against the migration lock tableRequired handlingCaller MUST wrap await knex.migrate.forceFreeMigrationsLock() in try-catch. Surface failures loudly — a failed unlock means the service cannot recover its ability to migrate.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - migrate.forceFreeMigrationsLock · migrate-force-free-lock-races-active-migrationerrorWhenforceFreeMigrationsLock() called while another process is actively running a migration (rather than the documented recovery case of a crashed migration)Throws
does not throw — silently clears the lock and allows a concurrent migrationRequired handlingOperator MUST verify no other migration process is running before calling forceFreeMigrationsLock(). Treat this function as a manual operator tool, never wire it into automated deploy scripts that run unconditionally.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - seed.run · seed-run-no-try-catcherrorWhenawait knex.seed.run(...) called without try-catchThrows
Error("Invalid seed file: <path> must have a seed function") if a file is missing the seed export; Error("Error while executing \"<path>\" seed: <original-message>") wrapping any error thrown from inside the seed function (including all knex query errors: insert constraint violations, connection failures, KnexTimeoutError); Error if the seed directory does not existRequired handlingCaller MUST wrap await knex.seed.run() in try-catch in test setup hooks and bootstrap scripts. Inspect err.original to recover the underlying knex error when reporting failures.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[18] - seed.run · seed-run-partial-state-on-failurewarningWhenseed.run() throws partway through a multi-file seed sequence without the caller rolling back already-inserted rows or truncating the affected tablesThrows
does not throw — leaves database in partially-seeded stateRequired handlingCaller SHOULD wrap seed.run() in an explicit transaction (or truncate-and-retry on failure) when partial-state recovery matters. At minimum, treat a failed seed.run() as a signal that the database needs cleanup before the next attempt.costlowin prodsilent failureusers seedegraded performancevisibilitysilentSources[18] - stream · stream-error-event-not-registerederrorWhenknex(...).stream() (or chained .stream()) consumed without registering an 'error' listener on the returned stream (or without try/catch around a for-await-of loop consuming it)Throws
does not throw from the .stream() call — errors are emitted asynchronously on the stream's 'error' event; an unhandled 'error' event terminates the Node.js process with an uncaught exceptionRequired handlingCaller MUST either (1) consume the stream with for-await-of inside try/catch, OR (2) register stream.on('error', handler) before piping, OR (3) use the callback form which returns a Promise that rejects on stream errors. Never .pipe() a knex stream without an 'error' listener.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[19] - stream · stream-not-destroyed-on-request-abortwarningWhenknex stream piped into an HTTP response is not explicitly destroyed when the HTTP request is aborted by the clientThrows
does not throw — the database connection is held open and remains in the pool as in-use until either query completion or KnexTimeoutErrorRequired handlingCaller MUST listen for the HTTP request's 'aborted' / 'close' event and call stream.destroy() to release the pooled connection. The for-await-of consumption form handles this automatically (the docs state: "if the loop terminates with a break, return, or a throw, the stream will be destroyed"). The raw-pipe form does not.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[19]
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]knexjs.org/guide/query-builder.htmlQuery Builder
- [2]knexjs.org/guide/query-builder.htmlQuery Builder
- [3]knexjs.org/guide/query-builder.htmlQuery Builder
- [4]knexjs.org/guide/query-builder.htmlQuery Builder
- [5]knexjs.org/guide/query-builder.htmlQuery Builder
- [6]knexjs.org/guide/raw.htmlRaw
- [7]knexjs.org/guide/raw.htmlRaw
- [8]knexjs.org/guideGuide
- [9]knexjs.org/guide/utility.htmlUtility
- [10]knexjs.org/guide/migrations.htmlMigrations
- [11]knexjs.org/guide/transactions.htmlTransactions
- [16]knexjs.org/guide/schema-builder.htmlSchema Builder
- [19]knexjs.org/guide/interfaces.htmlInterfaces
- [12]github.com/knex/knex/blobknex/knex · querybuilder.js
- [13]github.com/knex/knex/blobknex/knex · querybuilder.js
- [14]github.com/knex/knex/blobknex/knex · querybuilder.js
- [15]github.com/knex/knex/blobknex/knex · make-knex.js
- [17]github.com/knex/knex/blobknex/knex · builder.js
- [18]github.com/knex/knex/blobknex/knex · Seeder.js
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources: knex
Package: knex
Version: 3.x
Category: database (SQL query builder)
Status: ✅ Complete
Official Documentation
- Main Docs: https://knexjs.org/
- Query Builder: https://knexjs.org/guide/query-builder.html
- Transactions: https://knexjs.org/guide/transactions.html
- Schema: https://knexjs.org/guide/schema-builder.html
- Destroy: https://knexjs.org/guide/#destroy
- npm: https://www.npmjs.com/package/knex
Behavioral Requirements
SQL Errors: Syntax errors, constraint violations, type mismatches Connection Errors: Database down, auth failures Must wrap queries in try-catch to handle SQL errors Transactions must handle rollback on errors Must call destroy() on shutdown to close connections
Contract Rationale
SQL queries can fail: Syntax, constraints, connections Transaction errors leave database inconsistent: Must rollback Unclosed connections prevent graceful shutdown
Created: 2026-02-26 Status: ✅ COMPLETE