vercel/ai · error · RunError

error.message

Error message

error.message

What it means

In invokeCodeModeTool's catch block, errors that are already CodeModeError instances (e.g. protocol, size-limit, or timeout errors raised during tool invocation) are recorded and rethrown as a RunError carrying error.message (the message shown in this entry is a template placeholder — the actual message is the original CodeModeError's message). This preserves the specific code-mode error message and code across the sandbox host-function boundary so it can later be restored via findPreservedCodeModeError.

Source

Thrown at packages/code-mode/src/run-code-mode.ts:333

      toolName,
      inputJson,
      tools: input.tools,
      baseExecutionOptions,
      codeModeOptions: input.options ?? {},
      maxToolInputBytes: policy.maxToolInputBytes,
      maxToolOutputBytes: policy.maxToolOutputBytes,
      toolCallId,
      ...(codeModeInterrupt === undefined ? {} : { codeModeInterrupt }),
      skipApproval,
    });
    if (outcome.type === 'interrupted') {
      return context.interrupt(outcome.payload);
    }
    return fromJsonPayload(outcome.valueJson);
  } catch (error) {
    if (error instanceof CodeModeError) {
      codeModeErrors.push(error);
      throw new RunError(error.message, error.code, error.details);
    }
    if (
      RunError.isInstance(error) ||
      (error instanceof Error && error.name === 'HostFunctionInterruptSignal')
    ) {
      throw error;
    }
    throw new RunError('Host tool failed.', 'CODE_MODE_HOST_TOOL_ERROR');
  }
}

function assertInterruptPayload(value: unknown): CodeModeInterruptPayload {
  if (
    typeof value !== 'object' ||
    value === null ||
    Array.isArray(value) ||
    typeof (value as { kind?: unknown }).kind !== 'string'
  ) {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Read the RunError's message and code (e.g. CODE_MODE_TOOL_INPUT_TOO_LARGE) to identify the underlying limit or protocol violation.
  2. Shrink or restructure tool inputs in the sandbox code to fit maxToolInputBytes.
  3. Catch CodeModeError.isInstance around runCodeMode calls to access code and details for structured handling.

Example fix

// before
await runCodeMode({ js, tools }); // opaque failure
// after
try {
  await runCodeMode({ js, tools });
} catch (error) {
  if (CodeModeError.isInstance(error)) console.error(error.code, error.details);
  throw error;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate tool inputs in sandbox code before calling tools:
const inputJson = JSON.stringify(toolInput);
if (inputJson.length > maxToolInputBytes) throw new Error('tool input too large');

Try / catch

try {
  await runCodeMode({ js, tools });
} catch (error) {
  if (CodeModeError.isInstance(error)) {
    console.error(`code-mode failed: ${error.message}`, error.code, error.details);
  }
  throw error;
}

Prevention

When it happens

Trigger: Any nested CodeModeError thrown while invoking a host tool from sandbox code — e.g. tool input exceeding maxToolInputBytes, protocol errors in the interrupt machinery, or serialization failures — propagates out as a RunError with the original message.

Common situations: Passing oversized or non-serializable arguments to tools from generated code; hitting tool input/output byte limits configured in executionPolicy.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/0c876ee261732908. Report an issue: GitHub.