Skip to content

fix(module): surface tool errors as throwable exceptions in sandbox#208

Open
Mat4m0 wants to merge 1 commit intonuxt-modules:mainfrom
Mat4m0:fix/structured-error-handling-codemode
Open

fix(module): surface tool errors as throwable exceptions in sandbox#208
Mat4m0 wants to merge 1 commit intonuxt-modules:mainfrom
Mat4m0:fix/structured-error-handling-codemode

Conversation

@Mat4m0
Copy link
Copy Markdown

@Mat4m0 Mat4m0 commented Apr 6, 2026

The problem

Tool errors are opaque and uncatchable in code mode

When a tool returns isError: true, the dispatch function returns the error text as a regular value. The sandbox code has no way to distinguish an error from a successful string result, and try/catch never fires. Structured error details from structuredContent are also lost.

try {
  await codemode.delete_item({ id: "nonexistent" });
} catch (e) {
  // Never reached — error returned as plain string "Item not found"
}

Root cause

buildDispatchFunctions() passed isError results through the same text extraction path as successes, losing the error signal.

Solution

Dispatch side (index.ts): When result.isError is true, return a { __toolError, message, tool, details } sentinel object instead of extracting text. details carries result.structuredContent when available.

Sandbox side (executor.ts): The rpc() proxy detects the __toolError sentinel and throws a structured Error with .tool, .isToolError, and .details properties — making tool errors catchable with try/catch.

try {
  await codemode.delete_item({ id: "nonexistent" });
} catch (e) {
  e.isToolError // true
  e.tool        // "delete_item"
  e.message     // "Item not found"
  e.details     // { ok: false, error: { ... } } (if structuredContent present)
}

Note: Depends on #207 for structuredContent passthrough on success results. This PR only adds error handling.

Files changed

File What changed
index.ts buildDispatchFunctions(): check isError → return __toolError sentinel with details; export for testing
executor.ts Sandbox rpc() proxy: detect __toolError, throw structured Error
codemode.test.ts 5 new tests covering error dispatch

Test coverage

5 new tests in test/codemode.test.ts:

  • __toolError sentinel for isError results
  • structuredContent included as details in error sentinel
  • No details when no structuredContent
  • Non-error results unaffected
  • isError + structuredContent prioritizes error over structured data

All 150 tests pass (20 test files).

Test plan

  • pnpm test passes (150/150)
  • pnpm lint passes
  • tsc --noEmit passes
  • Tool returning isError: true → sandbox throws structured Error with .tool, .isToolError, .details
  • Tool returning isError: true + structuredContent → error sentinel includes details
  • Non-error tools unaffected by the change

AI tools used

  • Claude Opus 4.6

Tool errors (isError: true) were returned as plain strings, making them
indistinguishable from successful results in sandbox code. try/catch
never fires, and structured error details from structuredContent are
lost.

Return a __toolError sentinel from dispatch so the sandbox proxy can
throw a structured Error with .tool, .isToolError, and .details fields.
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 6, 2026

@Mat4m0 is attempting to deploy a commit to the Nuxt Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

Thank you for following the naming conventions! 🙏

@github-actions github-actions bot added the bug Something isn't working label Apr 6, 2026
@Mat4m0 Mat4m0 changed the title fix(codemode): surface tool errors as throwable exceptions in sandbox fix(module): surface tool errors as throwable exceptions in sandbox Apr 6, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 6, 2026

npm i https://pkg.pr.new/@nuxtjs/mcp-toolkit@208

commit: 5945ca9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant