Skip to content

console.log(ctx) / util.inspect(ctx.res) throws 'Cannot read private member #headersList' on Node (guarded stub headers) #1000

Closed

Description

@ivogt

console.log(ctx) in a handler, and util.inspect(ctx.res) or util.inspect(ctx.res.headers), throw on Node:

TypeError: Cannot read private member #headersList from an object whose class did not declare it

It happens in every scope, not only a cached one. On workerd there is no throw, because its Headers has no Node inspect hook.

Cause

The #713 response-header guard shadows the stub response's headers with a Proxy whose target is a fresh, empty new Headers(). Its get trap forwards to the real rawStubHeaders (packages/rangojs-router/src/server/request-context.ts:1199-1211 on bad36a6b). Node's util.inspect unwraps the Proxy and runs undici's Headers inspect hook. That hook reads #headersList from a receiver that is not a real Headers, and throws.

Repro

This mirrors the guard shape without any router code (Node 22.18):

import { inspect } from "node:util";
const raw = new Response(null).headers;
const guarded = new Proxy(new Headers(), {
  get(_t, prop) {
    const v = Reflect.get(raw, prop);
    return typeof v === "function" ? v.bind(raw) : v;
  },
});
inspect(guarded); // TypeError: Cannot read private member #headersList ...

Through the router: in any handler, console.log(ctx) or console.log(ctx.res) on the Node dev server.

Suggested fix

Give the guarded proxy an own [Symbol.for("nodejs.util.inspect.custom")] that inspects rawStubHeaders. Alternatively, have the trap handle that symbol. #976 / #999 takes the same approach for ctx.request. Add a unit test that inspects ctx, ctx.res and ctx.res.headers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions