vercel/ai · error
Tool relay ${schema.name} failed with ${res.status}: ${body.
Error message
Tool relay ${schema.name} failed with ${res.status}: ${body.slice(0, 500)} What it means
The in-sandbox MCP host-tool server relays each tool invocation to the host process over HTTP via TOOL_RELAY_URL. When the relay responds with a non-2xx status, the bridge turns it into an error containing the tool name, HTTP status, and the first 500 chars of the response body, which is then surfaced to the model as a tool error. This indicates the host-side relay endpoint rejected or failed to execute the tool call.
Source
Thrown at packages/harness-opencode/src/bridge/host-tool-mcp.ts:63
for (const schema of schemas) {
const shape = toZodShape(schema.inputSchema);
server.tool(
schema.name,
schema.description ?? '',
shape,
async (input: Record<string, unknown>) => {
const requestId = crypto.randomUUID();
try {
const res = await fetch(relayUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ requestId, toolName: schema.name, input }),
});
if (!res.ok) {
const body = await res.text();
throw new Error(
`Tool relay ${schema.name} failed with ${res.status}: ${body.slice(0, 500)}`,
);
}
const data = (await res.json()) as { result?: unknown };
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(data.result ?? null),
},
],
};
} catch (err) {
return {
content: [{ type: 'text' as const, text: `Error: ${String(err)}` }],
isError: true,
};
}View on GitHub (pinned to 69428b1f8b)
Solutions
- Check the response body in the error message for the relay's own error detail and fix the host-side tool implementation accordingly.
- Verify TOOL_RELAY_URL matches the host relay's actual address and port and that the relay process is still running.
- Retry the tool call; transient host restarts cause one-off 5xx responses.
- Ensure the sandbox can reach the host network (no firewall/network isolation blocking the relay).
Example fix
// before (host relay returning 500 because handler throws)
relay.post('/tool', async (req, res) => { await runTool(req.body); res.send(...) });
// after
relay.post('/tool', async (req, res) => {
try { const result = await runTool(req.body); res.json({ result }); }
catch (e) { console.error('tool failed', e); res.status(500).json({ error: String(e) }); }
}); Defensive patterns
Strategy: try-catch
Validate before calling
const relayOk = await fetch(process.env.TOOL_RELAY_URL, { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!relayOk) throw new Error('Tool relay unreachable before session start'); Type guard
function isToolRelayHttpError(e: unknown): e is Error & { message: string } {
return e instanceof Error && /^Tool relay .+ failed with \d{3}:/.test(e.message);
} Try / catch
try {
const result = await agent.run(...);
} catch (e) {
if (isToolRelayHttpError(e)) {
console.error('Relay status/body:', e.message);
// restart host relay, then retry the turn
} else throw e;
} Prevention
- Health-check TOOL_RELAY_URL before starting each sandbox session.
- Keep the host relay process supervised (auto-restart on crash).
- Pin the relay port and log every non-2xx response host-side.
- Include the tool name and status in host logs to correlate with this error.
When it happens
Trigger: Calling any bridged host tool from inside the OpenCode sandbox when the TOOL_RELAY_URL HTTP endpoint returns a non-OK status (400/404/500, etc.), e.g. the host relay process crashed, the URL points to the wrong port/path, or the host handler threw while executing the tool.
Common situations: Host process restarted or exited mid-session leaving the relay dead; misconfigured TOOL_RELAY_URL port; the host tool implementation itself raised an exception that the relay returned as a 500; auth/CORS proxy in front of the relay rejecting the POST.
Related errors
- Failed to fetch the response.
- The response body is empty.
- ${readErrorMessage({ value, status: response.status })}
- The host tool MCP relay is unavailable.
- Failed to download ${url}: ${statusCode} ${statusText}
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/74106e2f966f6b0b.
Report an issue: GitHub.