yikart/AiToEarn · error
-32600
-32600
Error message
Invalid Request: Only one initialization request is allowed
What it means
During stateful session setup, the server received an `initialize` request but the POST body was a JSON-RPC batch containing more than one request. The library rejects this with -32600 and HTTP 400 because batching multiple messages including initialize could create ambiguous session state; only a single initialize request is allowed per batch.
Source
Thrown at project/aitoearn-backend/libs/nest-mcp/src/services/mcp-streamable-http.service.ts:202
}
/**
* Handle requests in stateful mode
*/
async handleStatefulRequest(
req: HttpRequest,
res: HttpResponse,
body: unknown,
): Promise<void> {
const sessionId = req.headers['mcp-session-id'] as string | undefined
this.logger.debug(`[${sessionId || 'New'}] Handling stateful MCP request`)
// Case 1: New initialization request
if (!sessionId && this.isInitializeRequest(body)) {
// Validate it's not a batch with multiple requests
if (Array.isArray(body) && body.length > 1) {
res.status(400).json({
jsonrpc: '2.0',
error: {
code: -32600,
message:
'Invalid Request: Only one initialization request is allowed',
},
id: null,
})
return
}
// Build capabilities
const capabilities = buildMcpCapabilities(
this.mcpModuleId,
this.toolRegistry,
this.options,
)
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Send the initialize request alone as a single JSON-RPC object, not inside an array.
- Initialize first, capture the Mcp-Session-Id response header, then batch or pipeline subsequent calls on that session if needed.
- If your client must batch, batch only post-initialization requests on an established session.
Example fix
// before
await fetch(url, { method: 'POST', body: JSON.stringify([initReq, listToolsReq]) })
// after
const res = await fetch(url, { method: 'POST', body: JSON.stringify(initReq) })
const sessionId = res.headers.get('mcp-session-id')
await fetch(url, { method: 'POST', headers: { 'mcp-session-id': sessionId }, body: JSON.stringify(listToolsReq) }) Defensive patterns
Strategy: validation
Validate before calling
const isBatch = Array.isArray(body)
if (isBatch && body.some((r: any) => r?.method === 'initialize') && body.length > 1) {
throw new Error('initialize must be sent alone, not in a batch')
} Type guard
function isSingleInitialize(body: unknown): body is { jsonrpc: '2.0'; method: 'initialize'; id: string | number } {
return !Array.isArray(body) && typeof body === 'object' && body !== null && (body as any).method === 'initialize'
} Try / catch
if (res.status === 400 && (await res.json())?.error?.code === -32600) {
// resend initialize as a single, non-batched request
} Prevention
- Always send initialize as a single JSON-RPC object.
- Only batch requests after initialization, on an established session.
- Review proxy/gateway code that merges or coalesces client requests into arrays.
When it happens
Trigger: POSTing a JSON array like `[ {initialize...}, {tools/list...} ]` (or any array with length > 1 where an element is an initialize request) to the MCP endpoint without a session ID.
Common situations: Clients implementing JSON-RPC batch support too aggressively, proxy/gateway code that coalesces requests into an array, or hand-rolled test scripts sending arrays of messages at once.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/fb7ab637e9034199.
Report an issue: GitHub.