denoland/deno · error · TypeError
ERR_HTTP_INVALID_HEADER_VALUE
ERR_HTTP_INVALID_HEADER_VALUE
Error message
Invalid value "${value}" for header "${name}" What it means
validateHeaderValue() throws ERR_HTTP_INVALID_HEADER_VALUE when the value is exactly undefined. Unlike null (which later serializes as a string), an undefined value means 'key present but no value' - almost always a bug such as reading a missing property - so setting it is rejected instead of silently sending garbage.
Solutions
- Default the value: setHeader('x-id', obj.id ?? '') or skip the header when it is undefined.
- Fix the source so the property is actually set, or pass null instead of undefined if an empty-ish header is intended.
- Add a filter step when bulk-importing header objects: drop entries whose value === undefined.
Example fix
// before
res.setHeader('x-request-id', ctx.requestId); // undefined
// after
if (ctx.requestId !== undefined) res.setHeader('x-request-id', ctx.requestId); Defensive patterns
Strategy: validation
Validate before calling
function hasHeaderValue(v) {
return v !== undefined;
}
for (const [k, v] of Object.entries(headerObj)) {
if (v !== undefined) res.setHeader(k, v); // skip undefined instead of throwing
} Type guard
type DefinedHeaderRecord = Record<string, string | string[] | null>;
function hasNoUndefinedHeaders(h) {
return Object.values(h).every((v) => v !== undefined);
} Prevention
- Filter undefined entries when bulk-importing header objects.
- Default optional fields at the source: config.id ?? ''.
- In TypeScript, type header values as string | null to make undefined unrepresentable.
When it happens
Trigger: res.setHeader('x-id', obj.missingProp); writeHead(200, { 'x-tag': undefined }); appendHeader('x-opt', options.feature) where options.feature was never set.
Common situations: Optional config fields forwarded straight into headers; destructuring with a typo'd key; JSON payloads where a field is absent rather than null; TypeScript code where a possibly-undefined field slips past checks.
Related errors
- ERR_HTTP_HEADERS_SENT
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_HTTP_TOKEN
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/f61ad013a4fd1c92.
Report an issue: GitHub.
Appendix: source
Thrown at ext/node/polyfills/_http_outgoing.ts:1327
}
},
"OutgoingMessage.prototype._headerNames is deprecated",
"DEP0066",
),
});
export const validateHeaderName = hideStackFrames(
(name: string, label?: string): void => {
if (typeof name !== "string" || !name || !checkIsHttpToken(name)) {
throw new ERR_INVALID_HTTP_TOKEN(label || "Header name", name);
}
},
);
export const validateHeaderValue = hideStackFrames(
(name: string, value: string): void => {
if (value === undefined) {
throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
}
if (checkInvalidHeaderChar(value)) {
debug('Header "%s" contains invalid characters', name);
throw new ERR_INVALID_CHAR("header content", name);
}
},
);
export function parseUniqueHeadersOption(headers) {
if (!ArrayIsArray(headers)) {
return null;
}
const unique = new SafeSet();
const l = headers.length;
for (let i = 0; i < l; i++) {
unique.add(StringPrototypeToLowerCase(headers[i]));
}View on GitHub (pinned to 9ad36f7a2c)