vercel/ai · error · TypeError
Tool argument "${binding.path.join('.')}" does not match its
Error message
Tool argument "${binding.path.join('.')}" does not match its x-mcp-header type What it means
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.
Source
Thrown at packages/mcp/src/tool/mcp-http-headers.ts:150
args,
}: {
bindings: MCPToolHeaderBinding[];
args: Record<string, unknown>;
}): Record<string, string> {
const headers: Record<string, string> = {};
for (const binding of bindings) {
const value = getValueAtPath(args, binding.path);
if (value == null) {
continue;
}
if (
(binding.valueType === 'string' && typeof value !== 'string') ||
(binding.valueType === 'boolean' && typeof value !== 'boolean') ||
(binding.valueType === 'integer' && !Number.isSafeInteger(value))
) {
throw new TypeError(
`Tool argument "${binding.path.join('.')}" does not match its x-mcp-header type`,
);
}
headers[`Mcp-Param-${binding.headerName}`] = encodeMCPHeaderValue(
String(value),
);
}
return headers;
}
View on GitHub (pinned to 69428b1f8b)
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
Example fix
// before
await tool.execute({ requestId: 42, dryRun: "true" });
// after
await tool.execute({ requestId: "42", dryRun: true }); Defensive patterns
Strategy: validation
Validate before calling
function assertHeaderArg(name, value, valueType) {
const ok = valueType === 'string' ? typeof value === 'string'
: valueType === 'boolean' ? typeof value === 'boolean'
: valueType === 'integer' ? typeof value === 'number' && Number.isSafeInteger(value)
: false;
if (!ok) throw new TypeError(`argument ${name} must be ${valueType} for its x-mcp-header`);
}
// call before tool execution for each header-bound argument Type guard
function matchesHeaderType(value: unknown, valueType: 'string' | 'boolean' | 'integer'): value is string | boolean | number {
return (valueType === 'string' && typeof value === 'string') ||
(valueType === 'boolean' && typeof value === 'boolean') ||
(valueType === 'integer' && typeof value === 'number' && Number.isSafeInteger(value));
} Try / catch
try {
await tool.execute(args);
} catch (error) {
if (error instanceof TypeError && error.message.includes('x-mcp-header type')) {
// coerce/validate the offending argument and retry
} else throw error;
} Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- maxEmbeddingsPerCall must be greater than 0
- maxInputBytesPerCall must be greater than 0
- No image generated.
- No object generated: the model did not return a response.
- Invalid argument for parameter output: Invalid output type.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/168b12fe20350cba.
Report an issue: GitHub.