websockets/ws · error · SyntaxError
Unexpected end of input
Error message
Unexpected end of input
What it means
Thrown by `extension.parse()` after the loop ends, when the final state is incomplete: `start === -1` (the parser was mid-way expecting another token but got end-of-input), `inQuotes === true` (an unterminated quoted value), or the last consumed character was a space/tab (trailing whitespace after a value that needed a separator or end). The message has no index because the failure is at EOF.
Solutions
- Terminate every quoted value with a closing `"` and ensure the header ends with a complete token.
- Remove trailing separators and trailing whitespace.
- Catch the SyntaxError and close the connection with code 1002.
Example fix
// before — unterminated quoted value
const offers = extension.parse('permessage-deflate; key="unterminated');
// after — close the quote
const offers = extension.parse('permessage-deflate; key="terminated"'); Defensive patterns
Strategy: try-catch
Try / catch
const { parse } = require('ws/lib/extension');
try {
const offers = parse(header);
} catch (err) {
if (err instanceof SyntaxError) {
// Truncated header: unterminated quote, trailing separator, or trailing space.
abortHandshake(socket, 1002);
return;
}
throw err;
} Prevention
- Terminate every quoted value with a closing `"` and end the header on a complete token.
- Strip trailing separators and whitespace before parsing.
- Treat any 'Unexpected end of input' SyntaxError as a protocol error (close 1002).
When it happens
Trigger: Calling `extension.parse('permessage-deflate; key="unterminated')` (unclosed quote), `extension.parse('permessage-deflate;')` (trailing separator with nothing after), or `extension.parse('permessage-deflate; key=value ')` (trailing space).
Common situations: A peer truncates the header mid-value (MTU/proxy bug); a hand-edited header left unterminated; a trailing space from string concatenation.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unexpected character at index
- First argument must be a valid error code number
- Parameter " " must have only a single value
- The data size must not be greater than 125 bytes
- The message must not be greater than 123 bytes
AI-assisted analysis of websockets/ws@c791e707ea (2026-08-06).
Data as JSON: /api/errors/09e75ef415ffc20c.
Report an issue: GitHub.
Appendix: source
Thrown at lib/extension.js:151
mustUnescape = false;
}
push(params, paramName, value);
if (code === 0x2c) {
push(offers, extensionName, params);
params = Object.create(null);
extensionName = undefined;
}
paramName = undefined;
start = end = -1;
} else {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
}
}
if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {
throw new SyntaxError('Unexpected end of input');
}
if (end === -1) end = i;
const token = header.slice(start, end);
if (extensionName === undefined) {
push(offers, token, params);
} else {
if (paramName === undefined) {
push(params, token, true);
} else if (mustUnescape) {
push(params, paramName, token.replace(/\\/g, ''));
} else {
push(params, paramName, token);
}
push(offers, extensionName, params);
}
return offers;View on GitHub (pinned to c791e707ea)