{"record":{"id":"851c245d06d4f9dd","repo":"vercel/ai","slug":"code-mode-host-tool-error","errorCode":"CODE_MODE_HOST_TOOL_ERROR","errorMessage":"Host tool failed.","messagePattern":"Host tool failed\\.","errorType":"exception","errorClass":"RunError","httpStatus":null,"severity":"error","filePath":"packages/code-mode/src/run-code-mode.ts","lineNumber":341,"sourceCode":"      ...(codeModeInterrupt === undefined ? {} : { codeModeInterrupt }),\n      skipApproval,\n    });\n    if (outcome.type === 'interrupted') {\n      return context.interrupt(outcome.payload);\n    }\n    return fromJsonPayload(outcome.valueJson);\n  } catch (error) {\n    if (error instanceof CodeModeError) {\n      codeModeErrors.push(error);\n      throw new RunError(error.message, error.code, error.details);\n    }\n    if (\n      RunError.isInstance(error) ||\n      (error instanceof Error && error.name === 'HostFunctionInterruptSignal')\n    ) {\n      throw error;\n    }\n    throw new RunError('Host tool failed.', 'CODE_MODE_HOST_TOOL_ERROR');\n  }\n}\n\nfunction assertInterruptPayload(value: unknown): CodeModeInterruptPayload {\n  if (\n    typeof value !== 'object' ||\n    value === null ||\n    Array.isArray(value) ||\n    typeof (value as { kind?: unknown }).kind !== 'string'\n  ) {\n    throw new CodeModeProtocolError(\n      'Code mode interruption payload is malformed.',\n    );\n  }\n  return value as CodeModeInterruptPayload;\n}\n\nfunction toRunLimits(","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/code-mode/src/run-code-mode.ts#L323-L359","documentation":"When a host tool invoked from code-mode sandbox code throws an error that is neither a CodeModeError, a RunError, nor the internal HostFunctionInterruptSignal, invokeCodeModeTool replaces it with a generic RunError('Host tool failed.', 'CODE_MODE_HOST_TOOL_ERROR'). This avoids leaking arbitrary tool implementation errors (which may contain sensitive details) into the sandbox, at the cost of hiding the original message.","triggerScenarios":"A tool's execute function throws a plain Error (network failure, unhandled exception, assertion) during a code-mode run; the error does not carry a code-mode error class so it is anonymized.","commonSituations":"Tools calling external HTTP APIs that go down; tool implementations with bugs that throw raw Errors; SDK version drift where a tool throws a new error type not recognized by the bridge.","solutions":["Check the tool's own logs/server-side for the underlying exception — the original message is intentionally not forwarded to the sandbox.","Make the tool catch its own errors and return a structured error value (or throw a CodeModeError with details) instead of a raw Error.","Add retry/error handling inside the tool execute function for transient failures like network errors."],"exampleFix":"// before\nexecute: async input => { const res = await fetch(url); return await res.json(); } // raw throw -> 'Host tool failed.'\n// after\nexecute: async input => {\n  try {\n    const res = await fetch(url);\n    return await res.json();\n  } catch (e) {\n    return { error: 'fetch_failed', detail: String(e) };\n  }\n}","handlingStrategy":"try-catch","validationCode":"// Harden tools so they never throw raw errors:\nconst safeTools = Object.fromEntries(Object.entries(tools).map(([name, tool]) => [name, wrapTool(tool)]));\n// wrapTool catches errors and returns { error: string } instead of throwing.","typeGuard":null,"tryCatchPattern":"try {\n  await runCodeMode({ js, tools });\n} catch (error) {\n  if (RunError.isInstance(error) && error.code === 'CODE_MODE_HOST_TOOL_ERROR') {\n    // check the tool's own logs for the real cause\n  }\n  throw error;\n}","preventionTips":["Wrap every tool execute with try/catch and return structured error values.","Add retries inside tools for transient network failures.","Monitor tool implementations for unhandled exceptions; the sandbox will only show the generic message."],"tags":["code-mode","host-tool","error-wrapping","sandbox"],"backgroundTag":"host-tool-failed","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}