Summary
DispatchOptions.upgrade currently accepts boolean in the public TypeScript type, but the runtime request validator rejects any truthy non-string value with InvalidArgumentError: upgrade must be a string. A TypeScript-valid call such as client.dispatch({ path: '/', method: 'GET', upgrade: true }, handler) therefore fails before any connector/network dispatch.
Code path
Producer / validator / feedback anchors:
types/dispatcher.d.ts:116-117: upgrade?: boolean | string | null;
lib/core/request.js:134-136: truthy upgrade values are rejected unless typeof upgrade === 'string'.
lib/dispatcher/dispatcher-base.js:172-180: the validator failure is surfaced through handler.onResponseError(null, err) and dispatch() returns false when the handler has an error hook.
Steps to reproduce
Validation level: dynamic reproduction plus source-control-flow validation.
const { Client } = require('undici')
const client = new Client('http://127.0.0.1:9', {
connect () {
throw new Error('connector should not be reached when option validation fails')
},
})
const handler = {
onRequestStart () {},
onResponseStart () {},
onResponseData () {},
onResponseEnd () {},
onResponseError (_controller, err) {
console.log(`handler.error.name=${err.name}`)
console.log(`handler.error.message=${err.message}`)
},
}
console.log(client.dispatch({ path: '/', method: 'GET', upgrade: true }, handler))
Observed output from the local repro:
handler.error.name=InvalidArgumentError
handler.error.message=upgrade must be a string
dispatch_return=false
Expected behavior
The public type and runtime validator should agree on the upgrade option contract. Either boolean should be rejected by TypeScript, or true should be normalized to a well-defined upgrade token.
Actual behavior
The TypeScript surface permits upgrade: true, but runtime rejects it before dispatch and reports upgrade must be a string.
Existing coverage
I searched current open/closed issues and PRs for upgrade must be a string, DispatchOptions upgrade boolean, and related types/dispatcher.d.ts upgrade terms. I did not find exact coverage. Nearby upgrade/WebSocket issues and PRs appear to cover protocol behavior, not this type/runtime option drift.
Suggested fix
The lower-risk fix is to narrow DispatchOptions.upgrade to string | null, matching the current runtime validator. If boolean support is intended, the runtime should define and test what true means.
Suggested tests
- Add a type-level negative assertion for
upgrade: true on DispatchOptions if narrowing the type.
- Keep or add a runtime test that
upgrade: 'websocket' remains accepted.
- Keep invalid non-string runtime values flowing to
onResponseError.
Submitted with Codex.
Summary
DispatchOptions.upgradecurrently acceptsbooleanin the public TypeScript type, but the runtime request validator rejects any truthy non-string value withInvalidArgumentError: upgrade must be a string. A TypeScript-valid call such asclient.dispatch({ path: '/', method: 'GET', upgrade: true }, handler)therefore fails before any connector/network dispatch.Code path
Producer / validator / feedback anchors:
types/dispatcher.d.ts:116-117:upgrade?: boolean | string | null;lib/core/request.js:134-136: truthyupgradevalues are rejected unlesstypeof upgrade === 'string'.lib/dispatcher/dispatcher-base.js:172-180: the validator failure is surfaced throughhandler.onResponseError(null, err)anddispatch()returnsfalsewhen the handler has an error hook.Steps to reproduce
Validation level: dynamic reproduction plus source-control-flow validation.
Observed output from the local repro:
Expected behavior
The public type and runtime validator should agree on the
upgradeoption contract. Eitherbooleanshould be rejected by TypeScript, ortrueshould be normalized to a well-defined upgrade token.Actual behavior
The TypeScript surface permits
upgrade: true, but runtime rejects it before dispatch and reportsupgrade must be a string.Existing coverage
I searched current open/closed issues and PRs for
upgrade must be a string,DispatchOptions upgrade boolean, and relatedtypes/dispatcher.d.ts upgradeterms. I did not find exact coverage. Nearby upgrade/WebSocket issues and PRs appear to cover protocol behavior, not this type/runtime option drift.Suggested fix
The lower-risk fix is to narrow
DispatchOptions.upgradetostring | null, matching the current runtime validator. If boolean support is intended, the runtime should define and test whattruemeans.Suggested tests
upgrade: trueonDispatchOptionsif narrowing the type.upgrade: 'websocket'remains accepted.onResponseError.Submitted with Codex.