denoland/deno · error · TypeError
Invalid status text: "${init.statusText}"
Error message
Invalid status text: "${init.statusText}" What it means
initializeAResponse validates a non-empty init.statusText against REASON_PHRASE_RE (printable ASCII reason-phrase characters; control bytes and non-ASCII such as \n, \r, or UTF-8 multibyte characters fail). A mismatch throws TypeError 'Invalid status text: "<value>"'.
Source
Thrown at ext/fetch/23_response.js:528
response,
init,
bodyWithType,
prefix,
context,
) {
// 1.
if ((init.status < 200 || init.status > 599) && init.status != 101) {
throw new RangeError(
`The status provided (${init.status}) is not equal to 101 and outside the range [200, 599]`,
);
}
// 2.
if (
init.statusText &&
RegExpPrototypeExec(REASON_PHRASE_RE, init.statusText) === null
) {
throw new TypeError(
`Invalid status text: "${init.statusText}"`,
);
}
// 3.
response[_response].status = init.status;
// 4.
response[_response].statusMessage = init.statusText;
// 5.
if (init.headers !== undefined) {
const list = responseHeaderList(response);
if (
!tryFillSingleContentTypeHeader(
list,
init.headers,
)
) {View on GitHub (pinned to 89f33cbef2)
Solutions
- Keep statusText to plain printable ASCII (or omit it — the standard phrase is used)
- Move rich messages into the JSON body or a custom header
- Sanitize: statusText.replace(/[^\x20-\x7e\t]/g, '') before passing it
Example fix
// before
return new Response(null, {
status: 400,
statusText: 'Bad Request — missing id', // em dash is invalid
});
// after
return Response.json({ error: 'Bad Request: missing id' }, { status: 400 }); Defensive patterns
Strategy: validation
Validate before calling
const REASON_PHRASE = /^[\x09\x20-\x7e\x80-\xff]*$/; // be conservative: ASCII only
function sanitizeStatusText(text) {
const t = String(text ?? '');
return /^[\x20-\x7e\t]*$/.test(t) ? t : '';
} Type guard
const isValidStatusText = (t) => t == null || t === '' || /^[\x09\x20-\x7e]+$/.test(String(t));
Prevention
- Keep statusText to printable ASCII; put detail in the body
- Strip control characters and non-ASCII from interpolated messages
- Prefer Response.json({ error }) over custom status phrases
When it happens
Trigger: new Response(body, { status: 200, statusText: 'OK\n' }), statusText containing '\r', or a message with emoji/accented characters; statusText built by string interpolation of unsanitized data.
Common situations: Putting human-readable error messages (with punctuation like non-ASCII quotes or emoji) into statusText instead of the body; header-injection-style input flowing into statusText.
Related errors
- The status provided (${init.status}) is not equal to 101 and
- Invalid header: length must be 2, but is ${header.length}
- Invalid header name: "${name}"
- Cannot change header: headers are immutable
- The url passed into 'proxy.url' has an invalid scheme for th
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/aaefee41c809b22a.
Report an issue: GitHub.