ruvnet/RuView · error · McpError
-32602
-32602
Error message
Invalid arguments for tool "${rawName}": ${parsed.error.message} What it means
The RuView MCP server (tools/ruview-mcp/src/index.ts) validates every tool call's arguments with the tool's zod schema via schema.safeParse(args ?? {}). On failure it throws McpError(ErrorCode.InvalidParams), JSON-RPC code -32602, with the zod validation message embedded, so the client gets a structured error instead of tool output.
Source
Thrown at tools/ruview-mcp/src/index.ts:294
if (!tool) {
return {
content: [
{
type: "text" as const,
text: JSON.stringify({
ok: false,
error: `Unknown tool "${rawName}". Available tools: ${TOOLS.map((t) => t.name).join(", ")}`,
}),
},
],
isError: true,
};
}
const parsed = tool.schema.safeParse(args ?? {});
if (!parsed.success) {
throw new McpError(
ErrorCode.InvalidParams,
`Invalid arguments for tool "${rawName}": ${parsed.error.message}`
);
}
try {
const result = await tool.handler(parsed.data, config);
return {
content: [
{
type: "text" as const,
text: JSON.stringify(result, null, 2),
},
],
};
} catch (e: unknown) {
if (e instanceof McpError) throw e; // propagate typed errors unchanged
const message = e instanceof Error ? e.message : String(e);View on GitHub (pinned to 4685618388)
Solutions
- Read the tool's inputSchema from the tools/list response and shape arguments to exactly that schema.
- Fix the specific field named in the zod message embedded in the error text (it lists the path and the violated constraint).
- Make sure the MCP client sends arguments as a JSON object (not a stringified payload), and match client/server versions.
Example fix
// before
client.callTool({ name: 'ruview_guidance', arguments: JSON.stringify({ topic: 'overview', limit: 100 }) })
// after
client.callTool({ name: 'ruview_guidance', arguments: { topic: 'overview', limit: 10 } }) Defensive patterns
Strategy: validation
Validate before calling
// Fetch and enforce the server's own schema before calling
const { tools } = await client.listTools();
const tool = tools.find((t) => t.name === 'ruview_guidance');
// shape args strictly from tool.inputSchema (types, enums, min/max), e.g.:
const args = { topic: 'overview', limit: Math.min(20, Math.max(1, Number(rawLimit) || 20)) }; Try / catch
try {
const res = await client.callTool({ name: 'ruview_guidance', arguments: args });
} catch (e) {
if (e?.code === -32602 || /Invalid arguments for tool/.test(e?.message ?? '')) {
// e.message embeds the zod path + violated constraint; fix that field, do not retry unchanged
throw new Error(`schema violation calling ruview_guidance: ${e.message}`);
}
throw e;
} Prevention
- Derive arguments from the tools/list inputSchema instead of guessing parameter names.
- Send arguments as a JSON object, never a stringified payload.
- Upgrade MCP client and ruview-mcp server together to avoid schema drift.
When it happens
Trigger: Calling a ruview MCP tool with arguments that violate its schema: wrong types (limit as string), out-of-range values (ruview_guidance with limit 100), missing required fields, unknown tool-specific keys, or args serialized as a JSON string instead of a JSON object.
Common situations: Client/server schema drift after upgrading one side; hand-rolled MCP clients that pass arguments: JSON.stringify(payload); agents guessing parameter names; empty-string vs missing optional fields.
Related errors
- brain corpus exceeds 1000 records
- command must be a non-empty string
- args must be an array of strings
- timeoutMs must be a safe integer between 1000 and 1800000
- maxOutputBytes must be a positive safe integer
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/7998db63a18bf2b6.
Report an issue: GitHub.