pg-connection-string retains arbitrary query keys, so the driver's own
configuration key connectionTimeoutMillis reaches ConnectionParameters straight
from a URL — and it was not on the rejected list, while spellings that do
nothing were. Rejecting it closes that gap.
The precedence claims that guard was built on were partly wrong, so every source
was measured against the installed [email protected].0, a real blackhole listener, and a
real PostgreSQL rather than inferred from the merge:
statement_timeout=0 / =900000 server reported 0 and 15min — wins outright
query_timeout=0 overrides the field, but the parsed value is
the string "0", which is truthy, so every
query gets a 0 ms read timer and fails
nondeterministically — it breaks the client
rather than loosening the bound
connectionTimeoutMillis=0/900000 pollutes connectionParameters.connect_timeout
(10 -> 0 or 900 s), but that field only feeds
getLibpqConnectionString(), which the pure-JS
client never calls; the effective timer was
unchanged, with an explicit 500 ms still
expiring at ~500 ms either way
connect_timeout=0 no effect: recomputed from the explicit field
options=-c statement_timeout=… no effect, including a backslash-escaped
spelling — the named startup parameter wins
PGOPTIONS / PGCONNECT_TIMEOUT no effect
unrelated parameters no effect, deliberately untouched
Only statement_timeout is a genuine downgrade. The rest are rejected as
unsupported configuration and defense in depth: no legitimate DATABASE_URL
carries a driver option, the polluted connect_timeout would take effect on the
native binding, and query_timeout produces intermittent failures an operator
could not diagnose. That distinction is now stated where it was previously
asserted wrongly — the earlier comment and ADR text claimed connect_timeout
overrode the explicit field, which measurement disproved.
Rejection still happens at the one shared construction boundary, before any
pg.Client exists, with the existing fixed POSTGRES_MIGRATION_CONFIGURATION_INVALID
and no URL, host, port, credential, parameter, or value in the message. The
10 s defaults, narrower test overrides, Pass 2 TLS policy and its URL-conflict
checks, and every unrelated parameter are unchanged.
Co-Authored-By: Claude Opus 5 <[email protected]>