docs(coding-agent): clarify that tool errors must be thrown, not returned

Returning { isError: true } from a tool's execute function was silently
ignored - the agent loop only sets isError via the catch block. Fix the
with-deps example to throw instead, add a clear note in the Tool Definition
docs section, and update the Error Handling summary.

closes #1881
This commit is contained in:
Mario Zechner
2026-03-06 14:36:18 +01:00
parent e4172e68d0
commit b079003cf6
3 changed files with 15 additions and 6 deletions

View File

@@ -1340,6 +1340,18 @@ pi.registerTool({
});
```
**Signaling errors:** To mark a tool execution as failed (sets `isError: true` on the result and reports it to the LLM), throw an error from `execute`. Returning a value never sets the error flag regardless of what properties you include in the return object.
```typescript
// Correct: throw to signal an error
async execute(toolCallId, params) {
if (!isValid(params.input)) {
throw new Error(`Invalid input: ${params.input}`);
}
return { content: [{ type: "text", text: "OK" }], details: {} };
}
```
**Important:** Use `StringEnum` from `@mariozechner/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
### Overriding Built-in Tools
@@ -1880,7 +1892,7 @@ const highlighted = highlightCode(code, lang, theme);
- Extension errors are logged, agent continues
- `tool_call` errors block the tool (fail-safe)
- Tool `execute` errors are reported to the LLM with `isError: true`
- Tool `execute` errors must be signaled by throwing; the thrown error is caught, reported to the LLM with `isError: true`, and execution continues
## Mode Behavior