{"record":{"id":"168b12fe20350cba","repo":"vercel/ai","slug":"tool-argument-binding-path-join-does-not","errorCode":null,"errorMessage":"Tool argument \"${binding.path.join('.')}\" does not match its x-mcp-header type","messagePattern":"Tool argument \"(.+?)\" does not match its x-mcp-header type","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/tool/mcp-http-headers.ts","lineNumber":150,"sourceCode":"  args,\n}: {\n  bindings: MCPToolHeaderBinding[];\n  args: Record<string, unknown>;\n}): Record<string, string> {\n  const headers: Record<string, string> = {};\n\n  for (const binding of bindings) {\n    const value = getValueAtPath(args, binding.path);\n    if (value == null) {\n      continue;\n    }\n\n    if (\n      (binding.valueType === 'string' && typeof value !== 'string') ||\n      (binding.valueType === 'boolean' && typeof value !== 'boolean') ||\n      (binding.valueType === 'integer' && !Number.isSafeInteger(value))\n    ) {\n      throw new TypeError(\n        `Tool argument \"${binding.path.join('.')}\" does not match its x-mcp-header type`,\n      );\n    }\n\n    headers[`Mcp-Param-${binding.headerName}`] = encodeMCPHeaderValue(\n      String(value),\n    );\n  }\n\n  return headers;\n}\n","sourceCodeStart":132,"sourceCodeEnd":162,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/mcp/src/tool/mcp-http-headers.ts#L132-L162","documentation":"createMCPToolHeaders maps tool arguments annotated with x-mcp-header into Mcp-Param-* HTTP headers. Each binding declares a valueType ('string' | 'boolean' | 'integer'); if the resolved argument value's runtime type does not match (non-string, non-boolean, or non-safe-integer), a TypeError is thrown rather than silently coercing the value into a header.","triggerScenarios":"Calling the tool with an argument bound to an x-mcp-header whose value is the wrong type: a number for a string header, a string \"true\" for a boolean header, a float/NaN/unsafe-integer for an integer header, or undefined/null when the argument is missing.","commonSituations":"Sending numeric IDs as numbers when the header binding declares string; LLM-produced tool arguments arriving as strings; values pulled through binding.path from a nested object being undefined because the caller omitted them.","solutions":["Pass the argument with the exact declared type: coerce strings to Number for integer headers (after validating Number.isSafeInteger), numbers to String for string headers, and real booleans (not \"true\"/\"false\" strings) for boolean headers","Validate or constrain the tool input schema (e.g. zod) so arguments bound to headers are guaranteed to have the declared type before invocation","Ensure the argument is always provided; missing values become undefined and fail the type check"],"exampleFix":"// before\nawait tool.execute({ requestId: 42, dryRun: \"true\" });\n// after\nawait tool.execute({ requestId: \"42\", dryRun: true });","handlingStrategy":"validation","validationCode":"function assertHeaderArg(name, value, valueType) {\n  const ok = valueType === 'string' ? typeof value === 'string'\n    : valueType === 'boolean' ? typeof value === 'boolean'\n    : valueType === 'integer' ? typeof value === 'number' && Number.isSafeInteger(value)\n    : false;\n  if (!ok) throw new TypeError(`argument ${name} must be ${valueType} for its x-mcp-header`);\n}\n// call before tool execution for each header-bound argument","typeGuard":"function matchesHeaderType(value: unknown, valueType: 'string' | 'boolean' | 'integer'): value is string | boolean | number {\n  return (valueType === 'string' && typeof value === 'string') ||\n    (valueType === 'boolean' && typeof value === 'boolean') ||\n    (valueType === 'integer' && typeof value === 'number' && Number.isSafeInteger(value));\n}","tryCatchPattern":"try {\n  await tool.execute(args);\n} catch (error) {\n  if (error instanceof TypeError && error.message.includes('x-mcp-header type')) {\n    // coerce/validate the offending argument and retry\n  } else throw error;\n}","preventionTips":["Enforce zod schema constraints (string/boolean/int) on header-bound tool arguments","Never pass string 'true'/'false' where boolean headers are expected; coerce with explicit Number()/String() helpers","Ensure header-bound arguments are always supplied (they become undefined otherwise)"],"tags":["type-mismatch","headers","validation"],"backgroundTag":"argument-type-mismatch","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}