Skip to content

fix(public-chat): a failed turn shows visitors a plain message, never the raw execution error (#3461) - #3478

Merged
vybe merged 1 commit into
devfrom
feature/3461-public-chat-failure-rendering
Oct 9, 2026
Merged

vybe merged 1 commit into
devfrom
feature/3461-public-chat-failure-rendering

Conversation

@trinity-ability

Copy link
Copy Markdown
Contributor

Description

  • Backend: the unauthenticated GET /api/public/executions/{token}/{id}/status returned execution.error verbatim for a failed row. It now answers the fixed line the synchronous public path already uses; the detail stays on the row for the operator. test_679_public_poll_cancel.py pinned the raw string for failed rows and now pins the fixed line.
  • Frontend: PublicChat.vue shows a plain failure message and restores the visitor's message into the input for a retry; it never renders the status route's error for a failed row.

Part of the UI sweep epic #3471.

Related Issue

Fixes #3461

Journey Impact

Journey Impact: none: bug fix to existing behaviour found by the UI sweep; no journey promise is added or changed

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Testing

  • I have tested this locally
  • New tests added (if applicable)
  • All existing tests pass
  • Every new test executes the changed path

Mutation: publicChatFailureMessage.spec.js — 4 red with the view change reverted. tests/unit/test_3461_public_status_failure_text.py — 2 red with the route change reverted (plus the updated #679 case). Restored byte-identical.

UI verification: on an isolated stack built from this change with a seeded failed execution whose stored error carries an exit code and operator remediation: the real /status response has error: "Failed to process your request. Please try again.", the page shows the plain banner, restores the message into the input, and none of the raw strings appear in the DOM or console; checked at 1440 and 768, light and dark. The submit response was simulated in the browser because the seeded agent has no container; polling, status and rendering were real.

Checklist

  • My code follows the project's style guidelines
  • I have updated the documentation (if applicable)
  • I have not committed any sensitive data (API keys, credentials, etc.)

🤖 Generated with Claude Code

…never the operator's error (#3461)

A public link's failed turn rendered the execution row's own `error` in
the chat banner: the agent server's diagnosis ("Execution failed with no
output (exit code 1): ...") followed by remediation addressed to the
operator. The page is read by anonymous visitors.

Two layers, because the page was only the last hop:

- `GET /api/public/executions/{token}/{id}/status` is unauthenticated and
  returned `execution.error` verbatim for a `failed` row. It now answers
  the fixed line the synchronous public path already answers; the detail
  stays on the row for the operator. A cancel reason (#679) and a skill
  gate's notice (trinity#3274) are written for the visitor and still pass
  through.
- `PublicChat.vue` no longer renders the status route's `error` for a
  failed turn at all. It shows one plain line and puts the visitor's
  message back in the input, so sending again is the retry.

Tests, each red with its fix reverted and green with it restored:
- src/frontend/tests/unit/publicChatFailureMessage.spec.js (mounted; 4/4
  red under mutation, incl. "never renders the execution row's own error
  text")
- tests/unit/test_3461_public_status_failure_text.py (2 red under
  mutation; the cancel and gate pass-through cases stay green)
- tests/unit/test_679_public_poll_cancel.py: the `failed` case pinned the
  raw string and now pins the fixed line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@vybe vybe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge-train: batch validated on train/20261009-2324-b (#3504)

@vybe
vybe merged commit c68b487 into dev Oct 9, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants