You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mcp: a request with malformed params (prompts/get with no name, tools/call with {}) answers JSON-RPC -32603 Internal error whose message is a raw Zod issue array, not -32602 Invalid params #29135
立卡门类别: ① 产品缺陷 — 具名落点 (packages/mcp/src/mcp-server-runtime.ts, where the server registers its request handlers over @modelcontextprotocol/sdk 1.32.1) + 复现.
reach: 公开入口实测一次错误结果 — POST /api/v1/mcp (API-key caller) {"jsonrpc":"2.0","id":1,"method":"prompts/get","params":{}} answers -32603 "Internal error" carrying a raw Zod issue array (stock showcase boot at 7fa9873, reproduced on three methods).
业务理由: an MCP client or agent that sends a malformed request is told the server failed (-32603), not that its own input was wrong (-32602), and the message is a JSON dump of Zod internals rather than a sentence. Agents treat Internal error as retryable and keep retrying a request that can never succeed; a developer reading the error looks for a server bug. Not doing it: every MCP client of the platform gets the wrong error class for its own mistakes.
动手的读者: the domain:server seat (mcp); triage first touch confirms the lane, then os-dev (a wrapper that maps request-schema parse failures to -32602 with a readable message, or an SDK upgrade if upstream already does).
查重: mcp -32603 → 0 hits; "-32602" mcp → 16 hits incl. closed, none about this. Not among the wave-4 MCP cards (#28937 record, #28938, #28939, #28940, #28943).
QA-source: #29124 · ai.mcp-http-surface · observed beside the clauses
Mechanism. The SDK's Protocol.setRequestHandler parses the incoming request with its schema; a ZodError carries no numeric JSON-RPC code, so the SDK maps it to ErrorCode.InternalError with the ZodError's message (the serialised issue list). The platform registers its handlers through that path and passes the result through unchanged. The behaviour is uniform across methods.
Reproduction (stock showcase, an osk_ API key minted for admin):
POST /api/v1/mcp {"jsonrpc":"2.0","id":1,"method":"prompts/get","params":{}} → {"error":{"code":-32603,"message":"[{\"expected\":\"string\",\"code\":\"invalid_type\",\"path\":[\"params\",\"name\"],…}]"}}.
tools/call with "params":{} → the same shape.
prompts/get with "params":{"name":42} → the same shape.
Control: validate_expression with an unknown site enum value → -32602 (the tool's own argument check answers correctly).
Expected: -32602 Invalid params with a readable message naming the missing or wrong param.
Actual: -32603 Internal error with a raw Zod issue array.
Read fresh. The fix lands where the MCP server registers its request handlers in packages/mcp/src/mcp-server-runtime.ts (map request-schema parse failures to -32602 with a readable message), so domain:server. It is p2 as a user-visible behaviour defect: every MCP client gets -32603 with a raw Zod dump for its own malformed params. It is a concrete defect with a named location and a three-method repro, so pm:queue; it was observed beside the clauses of QA run · release-18.3.0-w4-l1 (40/40) · 7fa9873f · 2026-11-02 · 37 PASS / 2 PARTIAL / 1 FAIL / 0 BLOCKED / 0 NOT-RUN #29124, not a FAIL of the item, so it is not p1.
Claim: PM loop round 1 · 2026-11-02T08:32Z
Session: session_01ADHkmQjPiXgNoSaEpqeGvY (seat); dev = card thread session_01ADHkmT3dPW9V7vSk6VKtuN
Account: os-steve
Branch: claude/project-thread-5zqs9f (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own
Domain: domain:server
Seat: domain:server#1
File surface: the request-handler registration of packages/mcp/src/** (mcp-server-runtime.ts, skill-prompts.ts): one seam mapping a request-schema parse failure to JSON-RPC -32602 with a readable sentence; its tests and a @objectstack/mcp changeset. ⛔ No packages/spec/**, no lockfile bump, no new gate. (stop on breach; explain in the report)
Container & model: S, mode:thread, model as the thread was opened, effort: medium
Clause-②: no (expected: the same malformed requests stay refused; only the JSON-RPC code and sentence change)
Metadata-protocol: none (expected)
Responsibility: the code is the MCP server runtime of @objectstack/mcp over the SDK's request parsing · the platform path is a malformed MCP request answered as a server fault (-32603) with a raw Zod dump · reached by every MCP client and agent, HTTP and stdio, today
Thread-read: 6572494368
Premise: holds (seat read on maind659c1d; the dev re-measures on base first)
Serial constraints cleared: No open PR touches packages/mcp/src/**. Seat 2's #28938 edits packages/runtime/src/domains/mcp.ts; this card stays out of that file.
Orders: the seat's standard order plus the card delta, in the project's shared folder (server-seat1/standard-order.md, server-seat1/29135-delta.md).
{
"issue": 29135,
"status": "done",
"branch": "claude/project-thread-5zqs9f",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29205",
"session": "session_01ADHkmT3dPW9V7vSk6VKtuN",
"premise_still_valid": true,
"summary": "Both MCP transports now build their server through createPlatformMcpServer (packages/mcp/src/request-params.ts). It wraps every request dispatcher of the SDK's low-level Server and rethrows a synchronously thrown ZodError (the request-schema parse) as McpError InvalidParams (-32602) with one plain sentence per issue, such as 'params.name is required' or 'params.name must be a string'. Base 0d6d4061 measured -32603 plus the raw Zod issue array for prompts/get {}, tools/call {} and prompts/get name:42 over HTTP, and for tools/call {} over stdio. Head answers -32602 with the sentence. The validate_expression control is unchanged. Installed SDK 1.32.1 and latest 1.32.2 both rethrow the ZodError unchanged, so the gap is ours. No lockfile bump.",
"tests": "Head 7bff29ad: pnpm --filter @objectstack/mcp test -> Test Files 54 passed (54), Tests 651 passed (651). New src/request-params.test.ts has 7 cases: 4 over HTTP (prompts/get no name, tools/call {}, prompts/get name 42, initialize with no protocolVersion), 1 over stdio, 1 control, and 1 negative pin (a ZodError inside a handler keeps -32603). Runtime MCP domain tests (src/domains/mcp-federation-bridge, mcp-merged-skill-read, mcp-option-fields-read, mcp-package-object-discovery), run after building @objectstack/runtime^...: Test Files 4 passed (4), Tests 162 passed (162). Ablation 1 at 1d7f90e3 deleted the mapping call through scripts/ablation-replace.mjs (anchor 1->0): 5 failed / 2 passed, each 'expected -32603 to be -32602'. Ablation 2 widened the guard to also map rejected ZodErrors: only the negative pin failed ('expected -32602 to be -32603'), 6 passed. Both legs were restored, blob == HEAD, git diff HEAD empty. No build was needed for these ablations: the mcp tests import src through relative paths.",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 7bff29ad derived 59 commands, all run. 57 exited 0 on the first run. check-plugin-teardown-shape --self-test exited 3 (positive control outside the shallow clone) and exited 0 after git fetch --unshallow origin main. pnpm check:dual-build-cjs-loads exited 3, PREREQUISITE NOT MET (needs every package dist): NOT MEASURED locally, CI Lint & Repo Gates runs it. --ran with exit codes: '59 derived, 58 run, 1 NOT-MEASURED, 0 UNRUN'. pnpm --filter @objectstack/mcp typecheck: exit 0. eslint packages/mcp --no-inline-config: exit 0. CI on PR 29205: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "3 — mcp__github__issue_read (get x1, get_comments x2); no write tools",
"api_writes": "2 — fleet-write relay pr_create (objectstack-ai/objectstack#29205); post-stamped os-dev-report comment on #29135. git push is not a REST write.",
"open_questions": [
{
"question": "The seam reads the SDK's undeclared Protocol._requestHandlers map. No public hook sits between the request-schema parse and the error answer. Should an upstream report ask the SDK to answer a request-schema ZodError as InvalidParams itself?",
"options": [
"A Keep the guarded seam. Construction throws loudly if the field moves, and 5 pins red if the mapping is lost. File nothing upstream now",
"B Also report it to modelcontextprotocol/typescript-sdk, and delete the seam once a release maps it"
],
"recommendation": "B: the seam stays correct and guarded meanwhile, and the upstream fix lets it go. An external report is the maintainer's call."
}
],
"out_of_scope_findings": [],
"files_changed": [
".changeset/29135-mcp-malformed-params-invalid-params.md",
"packages/mcp/src/mcp-server-runtime.ts",
"packages/mcp/src/request-params.ts",
"packages/mcp/src/request-params.test.ts"
],
"line_budget": "302 changed lines (+300 / -2) across 4 files, none governed; under the 3000 threshold",
"deviations": [
"Waited on the verify2 background run once by a pgrep -f name lookup (read-only, no kill) before switching to recorded PIDs; AGENTS.md §8 asks for recorded PIDs only.",
"pnpm lint for packages/mcp: the package has no lint script, so the root lint command (eslint --no-inline-config) was run over packages/mcp, exit 0.",
"pnpm install ran once in the shared checkout before the worktree existed (no file edits there)."
]
}
ACCEPT → PR #29205 comment 6573517566 (head 7bff29ad73). Readied and auto-merge armed through the relay; lands when CI is green. For the maintainer: the fix reads the MCP SDK's private request-handler map because the SDK has no public hook; reporting the gap upstream is left to you.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: ai.mcp-http-surface
Triage:
domain:server· p2 ·pm:queue· 2026-11-02T08:23Z⛔ Not a claim.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Claim: PM loop round 1 · 2026-11-02T08:32Z
Session:
session_01ADHkmQjPiXgNoSaEpqeGvY(seat); dev = card threadsession_01ADHkmT3dPW9V7vSk6VKtuNAccount:
os-steveBranch:
claude/project-thread-5zqs9f(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own
Domain:
domain:serverSeat:
domain:server#1File surface: the request-handler registration of
packages/mcp/src/**(mcp-server-runtime.ts,skill-prompts.ts): one seam mapping a request-schema parse failure to JSON-RPC -32602 with a readable sentence; its tests and a@objectstack/mcpchangeset. ⛔ Nopackages/spec/**, no lockfile bump, no new gate. (stop on breach; explain in the report)Container & model:
S,mode:thread, model as the thread was opened,effort: mediumClause-②: no (expected: the same malformed requests stay refused; only the JSON-RPC code and sentence change)
Metadata-protocol: none (expected)
Responsibility: the code is the MCP server runtime of
@objectstack/mcpover the SDK's request parsing · the platform path is a malformed MCP request answered as a server fault (-32603) with a raw Zod dump · reached by every MCP client and agent, HTTP and stdio, todayThread-read: 6572494368
Premise: holds (seat read on
maind659c1d; the dev re-measures on base first)Serial constraints cleared: No open PR touches
packages/mcp/src/**. Seat 2's #28938 editspackages/runtime/src/domains/mcp.ts; this card stays out of that file.Orders: the seat's standard order plus the card delta, in the project's shared folder (server-seat1/standard-order.md, server-seat1/29135-delta.md).
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmT3dPW9V7vSk6VKtuN
os-dev-report
{ "issue": 29135, "status": "done", "branch": "claude/project-thread-5zqs9f", "pr": "https://github.com/objectstack-ai/objectstack/pull/29205", "session": "session_01ADHkmT3dPW9V7vSk6VKtuN", "premise_still_valid": true, "summary": "Both MCP transports now build their server through createPlatformMcpServer (packages/mcp/src/request-params.ts). It wraps every request dispatcher of the SDK's low-level Server and rethrows a synchronously thrown ZodError (the request-schema parse) as McpError InvalidParams (-32602) with one plain sentence per issue, such as 'params.name is required' or 'params.name must be a string'. Base 0d6d4061 measured -32603 plus the raw Zod issue array for prompts/get {}, tools/call {} and prompts/get name:42 over HTTP, and for tools/call {} over stdio. Head answers -32602 with the sentence. The validate_expression control is unchanged. Installed SDK 1.32.1 and latest 1.32.2 both rethrow the ZodError unchanged, so the gap is ours. No lockfile bump.", "tests": "Head 7bff29ad: pnpm --filter @objectstack/mcp test -> Test Files 54 passed (54), Tests 651 passed (651). New src/request-params.test.ts has 7 cases: 4 over HTTP (prompts/get no name, tools/call {}, prompts/get name 42, initialize with no protocolVersion), 1 over stdio, 1 control, and 1 negative pin (a ZodError inside a handler keeps -32603). Runtime MCP domain tests (src/domains/mcp-federation-bridge, mcp-merged-skill-read, mcp-option-fields-read, mcp-package-object-discovery), run after building @objectstack/runtime^...: Test Files 4 passed (4), Tests 162 passed (162). Ablation 1 at 1d7f90e3 deleted the mapping call through scripts/ablation-replace.mjs (anchor 1->0): 5 failed / 2 passed, each 'expected -32603 to be -32602'. Ablation 2 widened the guard to also map rejected ZodErrors: only the negative pin failed ('expected -32602 to be -32603'), 6 passed. Both legs were restored, blob == HEAD, git diff HEAD empty. No build was needed for these ablations: the mcp tests import src through relative paths.", "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 7bff29ad derived 59 commands, all run. 57 exited 0 on the first run. check-plugin-teardown-shape --self-test exited 3 (positive control outside the shallow clone) and exited 0 after git fetch --unshallow origin main. pnpm check:dual-build-cjs-loads exited 3, PREREQUISITE NOT MET (needs every package dist): NOT MEASURED locally, CI Lint & Repo Gates runs it. --ran with exit codes: '59 derived, 58 run, 1 NOT-MEASURED, 0 UNRUN'. pnpm --filter @objectstack/mcp typecheck: exit 0. eslint packages/mcp --no-inline-config: exit 0. CI on PR 29205: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "3 — mcp__github__issue_read (get x1, get_comments x2); no write tools", "api_writes": "2 — fleet-write relay pr_create (objectstack-ai/objectstack#29205); post-stamped os-dev-report comment on #29135. git push is not a REST write.", "open_questions": [ { "question": "The seam reads the SDK's undeclared Protocol._requestHandlers map. No public hook sits between the request-schema parse and the error answer. Should an upstream report ask the SDK to answer a request-schema ZodError as InvalidParams itself?", "options": [ "A Keep the guarded seam. Construction throws loudly if the field moves, and 5 pins red if the mapping is lost. File nothing upstream now", "B Also report it to modelcontextprotocol/typescript-sdk, and delete the seam once a release maps it" ], "recommendation": "B: the seam stays correct and guarded meanwhile, and the upstream fix lets it go. An external report is the maintainer's call." } ], "out_of_scope_findings": [], "files_changed": [ ".changeset/29135-mcp-malformed-params-invalid-params.md", "packages/mcp/src/mcp-server-runtime.ts", "packages/mcp/src/request-params.ts", "packages/mcp/src/request-params.test.ts" ], "line_budget": "302 changed lines (+300 / -2) across 4 files, none governed; under the 3000 threshold", "deviations": [ "Waited on the verify2 background run once by a pgrep -f name lookup (read-only, no kill) before switching to recorded PIDs; AGENTS.md §8 asks for recorded PIDs only.", "pnpm lint for packages/mcp: the package has no lint script, so the root lint command (eslint --no-inline-config) was run over packages/mcp, exit 0.", "pnpm install ran once in the shared checkout before the worktree existed (no file edits there)." ] }Stamped 2026-11-02T09:19Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
ACCEPT → PR #29205 comment 6573517566 (head
7bff29ad73). Readied and auto-merge armed through the relay; lands when CI is green. For the maintainer: the fix reads the MCP SDK's private request-handler map because the SDK has no public hook; reporting the gap upstream is left to you.objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Landed · 2026-11-02T10:43Z
1b22286b14, through the merge queuecompletedbyFixes #29135pm:dispatchedis removed. Seat record: claim 6572639208, seat ACCEPT 6573517566 (Clause-②: no, no contract review owed).