fix(chat): show blocked and redirected custom tool calls as failed
Description
Part 3 of the ENG-4416 stack. A custom tool call blocked by the SSRF check (or answered with a redirect) raised ToolCallException before any CustomToolDelta, so the step list said "get_meta_data completed".
CustomTool.run()now returns a failedCustomToolCallSummaryand emits aCustomToolDeltawithCustomToolErrorInfofor blocked destinations (status_code=None) and redirects (the 3xx code). This reuses the existing 401/403 error path, so the error also persists in history.CustomToolRenderershows "{tool} was blocked" with the error icon and error surface. HTTP failures keep "{tool} failed ({code})".- The LLM gets the same short message the user sees.
| Before | After | After reload | Mobile |
|---|---|---|---|
The last "Done" row is the timeline's turn-finished step (showDoneStep in useTimelineUIState), shown for every finished turn. It no longer reads as the tool's result.
How Has This Been Tested?
- Local ODS stack + gpt-4.1-mini: an OpenAPI plugin on
169.254.169.254.nip.io; asked chat to call it. Desktop, reload and mobile show "was blocked" and no "completed"; API log shows the metadata-IP refusal. pytest backend/tests/unit/onyx/tools/custom: 105 passed (blocked, redirect, and delta/summary parity cases).- New
CustomToolRenderer.test.tsx(blocked + HTTP failure). pre-commit(ty, ruff, tsc, oxlint) on touched files.
Additional Options
- [Optional] Please cherry-pick this PR to the latest release version.
Link to Devin session: https://app.devin.ai/sessions/09df74c24e19407bbf0e7ab775b5cb0a
Open in Devin Desktop: https://app.devin.ai/desktop/session/09df74c24e19407bbf0e7ab775b5cb0a?variant=devin
Requested by: @rohoswagger
Summary by cubic
Fixes custom tool calls blocked by the SSRF check or answered with a redirect so they show as failed instead of "completed" in the chat step list.
CustomTool.run()now returns a failedCustomToolCallSummaryand emits aCustomToolDeltawith error info for blocked destinations and redirects instead of raisingToolCallException, reusing the existing 401/403 error path so the error persists in history.CustomToolRenderershows "{tool} was blocked" with the error icon and error surface; HTTP failures keep "{tool} failed ({code})".- The LLM receives the same short message the user sees.
Summary by CodeRabbit
-
Bug Fixes
- Custom tool requests blocked by security checks or redirects now appear as structured failures instead of unexpected errors.
- Error details, including HTTP status codes where available, are consistently shown in the conversation.
- Blocked and authentication-related errors now display clear, non-collapsible status messages.
-
Localization
- Added blocked-tool status translations across supported languages.
-
Tests
- Added coverage for blocked destinations, redirects, HTTP failures, and error rendering.