different-ai/openwork · error · SafeProbeFailure
request_id_mismatch
request_id_mismatch
Error message
request_id_mismatch
What it means
parseJsonRpcResult throws SafeProbeFailure("request_id_mismatch") when the response's 'id' does not strictly equal the request id the probe generated. JSON-RPC correlation requires id echo; any mismatch indicates a response for a different request or a tampered/buggy server.
Source
Thrown at apps/server/src/agent-context-cloud-probe.ts:532
if (line.startsWith(":")) continue;
const colon = line.indexOf(":");
const field = colon < 0 ? line : line.slice(0, colon);
const rawValue = colon < 0 ? "" : line.slice(colon + 1);
const value = rawValue.startsWith(" ") ? rawValue.slice(1) : rawValue;
if (field === "event") event = value;
if (field === "data") data.push(value);
}
dispatch();
if (messages.length !== 1) throw new SafeProbeFailure("invalid_json");
return messages[0];
}
function parseJsonRpcResult(payload: unknown, requestId: string): Record<string, unknown> {
if (!isRecord(payload) || payload.jsonrpc !== "2.0") {
throw new SafeProbeFailure("invalid_jsonrpc_envelope");
}
if (Object.hasOwn(payload, "error")) throw new SafeProbeFailure("jsonrpc_error");
if (payload.id !== requestId) throw new SafeProbeFailure("request_id_mismatch");
if (!isRecord(payload.result)) throw new SafeProbeFailure("invalid_jsonrpc_envelope");
return payload.result;
}
function requireSupportedProtocolVersion(initializeResult: Record<string, unknown>): void {
const version = initializeResult.protocolVersion;
if (typeof version !== "string" || version.length === 0 || version.length > MAX_PROTOCOL_HEADER_LENGTH) {
throw new SafeProbeFailure("invalid_jsonrpc_envelope");
}
if (version !== MCP_PROTOCOL_VERSION) throw new SafeProbeFailure("unsupported_protocol_version");
}
function validateCatalog(rpcResult: Record<string, unknown>): { toolIds: string[]; totalToolCount: number } {
if (rpcResult.nextCursor !== undefined && rpcResult.nextCursor !== null) {
throw new SafeProbeFailure("pagination_unsupported");
}
if (!Array.isArray(rpcResult.tools) || rpcResult.tools.length > MAX_TOOL_COUNT) {
throw new SafeProbeFailure("invalid_catalog");View on GitHub (pinned to 2b7df46e8a)
Solutions
- Verify the server echoes the exact 'id' value from the request (same type and value)
- Test the endpoint with a single sequential request to rule out interleaving bugs
- Update the server's JSON-RPC implementation to a spec-compliant version
- Check for proxies that cache or reroute responses between concurrent clients
Example fix
// before (server)
res.write(JSON.stringify({jsonrpc:"2.0",id:"req-1",result})) // request id was 1 (number)
// after
res.write(JSON.stringify({jsonrpc:"2.0",id:requestId,result})) Defensive patterns
Strategy: validation
Validate before calling
const echoed = (body as Record<string, unknown> | null)?.id;
if (echoed !== requestId) throw new Error(`response id ${JSON.stringify(echoed)} does not match request id ${JSON.stringify(requestId)}`); Type guard
function hasMatchingId(payload: unknown, requestId: unknown): payload is { id: unknown } & Record<string, unknown> {
return typeof payload === "object" && payload !== null && (payload as Record<string, unknown>).id === requestId;
} Try / catch
try {
const result = parseJsonRpcResult(payload, requestId);
} catch (e) {
if (e instanceof SafeProbeFailure && e.code === "request_id_mismatch") {
// log both ids and body; treat server as non-compliant or serialized behind a misbehaving proxy
} else throw e;
} Prevention
- Use unique, monotonically generated numeric request ids per call
- Avoid proxies that multiplex/cache JSON-RPC responses
- Add a server contract test asserting exact id echo including type
When it happens
Trigger: Server responds with id: null, omits id, returns a string id where a number was sent (or vice versa), or echoes a stale id.
Common situations: Server implementation reuses or regenerates ids; a multiplexing proxy returns the wrong pending response; server coerces numeric ids to strings; concurrent requests interleaved incorrectly.
Related errors
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/503d4198f2ae670f.
Report an issue: GitHub.