nodejs / nodejs/undici

DispatchOptions.upgrade accepts boolean in types but runtime rejects it

Open Beginner friendly
#5,466 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
7.7k
Forks
879
Avg merge
2d 16h
Merged PRs (30d)
68

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with types/dispatcher.d.ts:116-117 and lib/core/request.js:134-136, then trace the error path in lib/dispatcher/dispatcher-base.js:172-180. Check the existing type-level and runtime test conventions for DispatchOptions and request validation. Done means the public upgrade contract matches runtime behavior, valid string upgrades remain accepted, and invalid values are covered through the handler error path.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.