Hidden Assumptions in kysely
13 assumptions this code never checks · 4 critical · spanning Resource, Shape, Contract, Ordering, Temporal, Scale, Domain, Environment
Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at kysely-org/kysely and picked out the few most likely to cause trouble. The full list is just below.
Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".
If connection pool is exhausted or connections become stale, queries hang forever without timeout or error, causing application deadlock
When database schema changes or returns unexpected types (NULL for NOT NULL columns, strings for numbers), Kysely returns incorrectly typed data that passes TypeScript checks but fails at runtime
Invalid connection configs or network issues cause cryptic pg.Pool errors that bubble up without context, making it unclear whether the issue is configuration, network, or database
Show everything (10 more)
Visitor pattern traverses OperationNode trees in dependency-correct order where referenced nodes (tables, columns) are visited before dependent nodes (expressions, conditions) that use them
If this fails: If traversal order is wrong, SQL generation produces invalid queries with undefined table aliases or column references, especially in complex joins and subqueries
src/operation-node/operation-node-visitor.ts:OperationNodeVisitor
Compiled query cache entries remain valid for the lifetime of the Kysely instance — cached SQL never becomes stale due to schema changes or dialect updates
If this fails: After database schema changes (column renames, table drops), cached queries contain outdated SQL that executes against non-existent objects, causing runtime SQL errors
src/query-compiler/default-query-compiler.ts:DefaultQueryCompiler
TypeScript's type system can handle arbitrarily complex nested generic types from chained query operations like selectFrom().join().where().select() without hitting compiler limits
If this fails: Extremely complex queries with many joins and subqueries cause TypeScript compilation to hang or fail with 'Type instantiation is excessively deep' errors
src/query-builder/select-query-builder.ts:SelectQueryBuilder
Parameter binding uses 1-based indexing ($1, $2, $3) and parameters array indices match PostgreSQL's parameter placeholder numbering exactly
If this fails: Off-by-one errors in parameter binding cause queries to use wrong values — $1 gets parameters[1] instead of parameters[0], leading to data corruption or query failures
src/dialect/postgres/postgres-query-compiler.ts:PostgresQueryCompiler
Database configuration from Config contains valid PostgreSQL connection parameters and the target database exists and is accessible when Pool is created
If this fails: Missing database, wrong credentials, or network issues cause pg.Pool creation to fail with connection errors that don't distinguish between configuration vs infrastructure problems
example/src/app.ts:App.constructor
All dialect-specific DatabaseConnection implementations handle parameter binding consistently and return QueryResult with the same structure — rows, numAffectedRows, insertId have identical semantics across PostgreSQL, MySQL, SQLite
If this fails: Switching dialects breaks applications that depend on specific result formats — MySQL returns insertId as number but PostgreSQL might return bigint, causing type mismatches
src/driver/database-connection.ts:DatabaseConnection.executeQuery
Memory usage scales linearly with query complexity and result set size — large result sets or deeply nested OperationNode trees don't cause exponential memory growth during compilation or execution
If this fails: Queries returning millions of rows or with hundreds of joins consume excessive memory, potentially causing out-of-memory crashes in production
src/query-executor/default-query-executor.ts:DefaultQueryExecutor
Database connection cleanup happens synchronously after this.#db.destroy() resolves — no queries are still executing or connections still active
If this fails: If queries are still running when destroy() is called, they might complete with connection errors or leave connections open, causing resource leaks
example/src/app.ts:App.stop
User-provided DatabaseSchema types accurately reflect actual database structure — table names, column names, and types match what exists in the database at runtime
If this fails: Outdated schema types cause TypeScript to allow queries against non-existent columns or tables, leading to runtime SQL errors that could have been caught at compile time
src/util/type-utils.ts:DatabaseSchema
SQL expressions created through ExpressionBuilder methods generate valid SQL for the target dialect — function calls, operators, and syntax variations are correctly translated
If this fails: Using PostgreSQL-specific functions in a MySQL dialect or vice versa generates invalid SQL that fails at execution time with database-specific error messages
src/expression/expression-builder.ts:ExpressionBuilder
See the full structural analysis of kysely: the pipeline, data models, and system behavior that put these assumptions in context.
Full analysis of kysely-org/kysely →Frequently Asked Questions
What does kysely assume that could break in production?
The one most likely to cause trouble: Connection pools maintain healthy connections indefinitely without timeouts or connection limits exhaustion — acquireConnection() waits infinitely for an available connection If this fails, If connection pool is exhausted or connections become stale, queries hang forever without timeout or error, causing application deadlock
How many hidden assumptions does kysely have?
CodeSea found 13 assumptions kysely relies on but never validates, 4 of them critical, spanning Resource, Shape, Contract, Ordering, Temporal, Scale, Domain, Environment. Most are routine — the analysis flags the two or three most likely to actually bite.
What is a hidden assumption?
Something the code depends on but never checks: a data shape, an ordering, an environment condition, a scale limit, or a contract with another service. It holds until the world it runs in changes, then fails silently.