dotnet/aspnetcore · error · Error
Invalid input for JSON hub protocol. Expected a string.
Error message
Invalid input for JSON hub protocol. Expected a string.
What it means
JsonHubProtocol only operates on TransferFormat.Text, so parseMessages requires a string. Passing an ArrayBuffer (or any non-string) violates the protocol contract: the interface permits ArrayBuffer for binary protocols, but the JSON implementation does not, so it throws an explicit error rather than failing mysteriously inside JSON.parse.
Source
Thrown at src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts:31
export class JsonHubProtocol implements IHubProtocol {
/** @inheritDoc */
public readonly name: string = JSON_HUB_PROTOCOL_NAME;
/** @inheritDoc */
public readonly version: number = 2;
/** @inheritDoc */
public readonly transferFormat: TransferFormat = TransferFormat.Text;
/** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.
*
* @param {string} input A string containing the serialized representation.
* @param {ILogger} logger A logger that will be used to log messages that occur during parsing.
*/
public parseMessages(input: string, logger: ILogger): HubMessage[] {
// The interface does allow "ArrayBuffer" to be passed in, but this implementation does not. So let's throw a useful error.
if (typeof input !== "string") {
throw new Error("Invalid input for JSON hub protocol. Expected a string.");
}
if (!input) {
return [];
}
if (logger === null) {
logger = NullLogger.instance;
}
// Parse the messages
const messages = TextMessageFormat.parse(input);
const hubMessages = [];
for (const message of messages) {
const parsedMessage = JSON.parse(message) as HubMessage;
if (typeof parsedMessage.type !== "number") {
throw new Error("Invalid payload.");View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure the hub protocol matches the transport's transfer format: JsonHubProtocol with Text, MessagePackHubProtocol with Binary.
- If you call parseMessages directly, coerce/decode the payload to a string first (e.g. new TextDecoder().decode(buffer)).
- Check that you did not accidentally pass an ArrayBuffer through a custom IHubProtocol decorator to the JSON protocol.
- Verify HttpConnectionOptions.transport and the negotiated protocol agree on text vs binary.
Example fix
// before const protocol = new JsonHubProtocol(); protocol.parseMessages(buffer /* ArrayBuffer */, logger); // throws // after const text = typeof input === 'string' ? input : new TextDecoder().decode(input); protocol.parseMessages(text, logger);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof input !== 'string') {
throw new TypeError('JsonHubProtocol.parseMessages requires a string; got ' + typeof input);
}
// or decode before calling
const text = typeof input === 'string' ? input : new TextDecoder().decode(input as ArrayBuffer); Type guard
function isStringPayload(v: unknown): v is string {
return typeof v === 'string';
} Try / catch
try {
protocol.parseMessages(text, logger);
} catch (e) {
if (e instanceof Error && e.message.includes('Expected a string')) {
// wrong protocol/transport pairing
}
throw e;
} Prevention
- Pair JsonHubProtocol only with TransferFormat.Text transports.
- Decode binary buffers to UTF-8 strings before handing them to the JSON protocol.
- Add a typeof check in any custom transport/protocol wrapper before delegating.
When it happens
Trigger: Calling JsonHubProtocol.parseMessages with an ArrayBuffer, or wiring a transport that delivers binary chunks (e.g. a MessagePack-style transport) into a JsonHubProtocol instance. Also triggered by a custom IHubProtocol wrapper that forwards raw bytes.
Common situations: Mixing the JSON hub protocol with a binary transfer format by accident, a custom transport that does not decode to string, or upgrading a MessagePack setup and forgetting to swap the protocol object.
Related errors
- Invalid payload.
- Invalid payload for StreamItem message.
- Invalid payload for Completion message.
- Invalid SequenceId for Ack message.
- Invalid SequenceId for Sequence message.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/c65b6e9400697642.
Report an issue: GitHub.