vercel/ai · error
Invalid host tool relay response.
Error message
Invalid host tool relay response.
What it means
Thrown by validateInvocationResult when the relay's /invoke response is not a well-formed invocation result: the body is not an object, lacks a string 'correlationToken', or has a non-boolean 'isError'. The bridge uses this to guarantee every tool invocation result handed to the MCP server has a correlation token matching the request.
Source
Thrown at packages/harness-acp/src/v1/bridge/host-tool-mcp.ts:154
typeof value.name === 'string' &&
(value.description === undefined ||
typeof value.description === 'string') &&
(value.inputSchema === undefined ||
(isRecord(value.inputSchema) && !Array.isArray(value.inputSchema)))
);
}
function validateInvocationResult({
value,
}: {
value: unknown;
}): HostToolMCPInvocationResult {
if (
!isRecord(value) ||
typeof value.correlationToken !== 'string' ||
(value.isError !== undefined && typeof value.isError !== 'boolean')
) {
throw new Error('Invalid host tool relay response.');
}
return {
output: value.output,
...(value.isError ? { isError: true } : {}),
correlationToken: value.correlationToken,
};
}
function readErrorMessage({
value,
status,
}: {
value: unknown;
status: number;
}): string {
return isRecord(value) && typeof value.error === 'string'
? value.error
: `Host tool relay returned HTTP ${status}.`;View on GitHub (pinned to 69428b1f8b)
Solutions
- Inspect the relay's /invoke handler and confirm it always echoes the request's correlationToken as a string in the response.
- Check relay and bridge package versions match; align to the same AI SDK release.
- Capture the raw response body to check for an enveloping proxy rewriting it.
- If 'isError' is set, ensure it is a JSON boolean (true/false), not the strings "true"/"false".
Example fix
// before: relay response
{ "output": "done" }
// after
{ "output": "done", "correlationToken": "<requestId from invoke>", "isError": false } Defensive patterns
Strategy: type-guard
Validate before calling
function isValidInvocationResponse(value) {
return (
value != null && typeof value === 'object' && !Array.isArray(value) &&
typeof value.correlationToken === 'string' &&
(value.isError === undefined || typeof value.isError === 'boolean')
);
}
// check before accepting the relay body as an invocation result Type guard
function isInvocationResult(value: unknown): value is HostToolMCPInvocationResult {
return (
value != null && typeof value === 'object' && !Array.isArray(value) &&
typeof (value as any).correlationToken === 'string' &&
((value as any).isError === undefined || typeof (value as any).isError === 'boolean')
);
} Try / catch
try {
const result = await invokeViaRelay({ toolName, input });
} catch (error) {
// 'Invalid host tool relay response.' => relay violated the /invoke contract;
// return an MCP tool error to the client rather than crashing the server.
return { isError: true, message: error instanceof Error ? error.message : String(error) };
} Prevention
- Add a relay contract test asserting correlationToken is echoed on every /invoke response.
- Keep relay and bridge on matching package versions.
- Ensure isError is serialized as a JSON boolean, never a string.
- Bypass or audit proxies/middleware that might rewrap the response body.
When it happens
Trigger: hostToolServer invoke -> postRelay('/invoke') returning HTTP 200 with a body that: is not a JSON object, omits 'correlationToken', has a non-string correlationToken, or has 'isError' set to a non-boolean value.
Common situations: Relay implementation bug dropping correlationToken on success paths; a middleware/proxy wrapping or replacing the response body; relay/bridge version mismatch after a wire-format change; relay echoing an error envelope with HTTP 200.
Related errors
- Invalid host tool catalog poll response.
- Invalid host tool catalog poll request.
- Invalid host tool catalog acknowledgment.
- Invalid host tool relay request.
- maxEmbeddingsPerCall must be greater than 0
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/455f9c956e05db2f.
Report an issue: GitHub.