different-ai/openwork · error · ProbeFailure
MCP_INITIALIZE
MCP_INITIALIZE
Error message
Initialize response JSON-RPC id did not match the request
What it means
This ProbeFailure is thrown during the initialize handshake of the enterprise MCP mock-server probe when the JSON-RPC response envelope's id does not equal the request id (1). The probe requires strict request/response correlation; a mismatched id means the response came from a different (or fabricated) request, so the probe aborts the MCP_INITIALIZE phase rather than trusting the payload. It is distinct from MCP_VERSION failures, which handle legitimate initialize errors.
Source
Thrown at packages/enterprise-mcp-mock-server/src/testing/probe.ts:755
if (initializeRawResponse.status === 401 || initializeRawResponse.status === 403) {
throw new ProbeFailure(
"AUTH_RESOURCE_VALIDATION",
initializeRawResponse.status === 403 ? "oauth_insufficient_scope" : "oauth_wrong_audience",
`MCP resource rejected the synthetic access token with HTTP ${initializeRawResponse.status}`,
)
}
const initializeResponse = await expectOk(initializeRawResponse, "MCP_INITIALIZE")
sessionId = initializeResponse.headers.get("mcp-session-id") ?? ""
negotiatedProtocolHeader = initializeResponse.headers.get("mcp-protocol-version") ?? scenario.protocol.version
const initializeEnvelope = await parseRpc(initializeResponse, "MCP_INITIALIZE")
if (initializeEnvelope.error) {
const versionEvidence = z.object({ supportedVersions: z.array(z.string()).min(1) }).safeParse(initializeEnvelope.error.data)
throw versionEvidence.success || initializeEnvelope.error.message === "Unsupported MCP protocol version"
? new ProbeFailure("MCP_VERSION", "mcp_version", initializeEnvelope.error.message)
: new ProbeFailure("MCP_INITIALIZE", "mcp_initialize", initializeEnvelope.error.message)
}
if (initializeEnvelope.id !== 1) {
throw new ProbeFailure("MCP_INITIALIZE", "mcp_initialize", "Initialize response JSON-RPC id did not match the request")
}
const initialize = parseAt(
initializeResultSchema,
initializeEnvelope.result,
"MCP_INITIALIZE",
"mcp_initialize",
"Initialize result did not match the required shape",
)
if (initialize.protocolVersion !== scenario.protocol.version) {
throw new ProbeFailure("MCP_VERSION", "mcp_version", "Server selected an unexpected MCP protocol version")
}
mutable.negotiatedProtocolVersion = initialize.protocolVersion
if (scenario.protocol.requireSession && !sessionId) {
throw new ProbeFailure("MCP_INITIALIZE", "mcp_initialize", "Initialize response omitted required MCP-Session-Id")
}
recordPassed(phases, "MCP_INITIALIZE", startedAt, "MCP version, capabilities, and session negotiated")
const sessionHeaders = {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Fix the MCP server/gateway to echo the request id verbatim in the initialize response
- Remove any caching or response-rewriting middleware between the probe and the MCP endpoint
- If the server batches responses, correlate responses by id before returning them to the client
- Run the probe directly against the endpoint (bypass proxies) to isolate where the id is altered
Example fix
// before (server)
res.json({ jsonrpc: "2.0", id: null, result: initializeResult })
// after (server)
res.json({ jsonrpc: "2.0", id: request.body.id, result: initializeResult }) Defensive patterns
Strategy: validation
Validate before calling
const env = rpcEnvelopeSchema.safeParse(body)
if (!env.success || env.data.id !== 1) throw new Error("initialize response id mismatch") Type guard
function isInitializeResponseForRequest1(e: { id?: unknown }): e is { id: number } {
return typeof e.id === "number" && e.id === 1
} Try / catch
try {
await probeEnterpriseMcpMockServer(scenario)
} catch (e) {
if (e instanceof ProbeFailure && e.code === "MCP_INITIALIZE") {
console.error("Initialize handshake failed:", e.message)
}
} Prevention
- Echo the JSON-RPC request id verbatim in every server response
- Avoid caching or rewriting JSON-RPC traffic in proxies
- Unit-test the server's initialize response shape including id
When it happens
Trigger: An HTTP 200 initialize response whose JSON body has an id other than 1 — e.g. the server echoes id: null, omits id, or returns the id of an unrelated notification/request.
Common situations: Proxy or gateway that rewrites or strips JSON-RPC ids; a server that batches or multiplexes responses out of order and pairs them incorrectly; middleware returning a cached response for a different request; a hand-rolled MCP server that hardcodes the response id.
Related errors
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/ef8e10a9c6466cf1.
Report an issue: GitHub.