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

  1. Fix the MCP server/gateway to echo the request id verbatim in the initialize response
  2. Remove any caching or response-rewriting middleware between the probe and the MCP endpoint
  3. If the server batches responses, correlate responses by id before returning them to the client
  4. 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

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.