Skip to content

Filter noisy invalid_request_error subtypes (e.g. thinking-signature) out of user-facing assistant text #87475

Description

@doralevich

Summary

formatAssistantErrorText in src/agents/embedded-agent-helpers/errors.ts returns LLM request rejected: ${raw_message} verbatim for any provider invalid_request_error. For most cases (malformed JSON, image-size, validation diagnostics) this is the correct call — the raw provider message has diagnostic value, and the existing test keeps non-streaming provider request-validation syntax diagnostics at src/agents/embedded-agent-helpers/errors.test.ts:48-55 documents that intent.

But some invalid_request_error subtypes produce text that is noise to end users and harmful in delivered channels. The clearest example is Anthropic's thinking-block signature rejection, e.g.:

LLM request rejected: messages.3.content.19: Invalid \signature` in `thinking` block`

This was a real production leak to a Telegram channel before the recent recovery wiring landed.

Now that wrapAnthropicStreamWithRecovery is wired in (#86886 / 66965f5008) the loop is gone, so this should be rare. But the same text can still reach the channel if the wrap's single-retry doesn't succeed, or for other invalid_request_error subtypes that are similarly opaque to a user (e.g. internal validation strings that name messages.N.content.M paths).

Filing this as a product-direction question rather than a fix-it PR because the existing behavior is deliberate and tested — changing it crosses an owner-decision line.

Real-world observation

Two separate production occurrences on a Mac-mini Telegram-bot install (channel dev, 2026.5.22 at the time):

  • 2026-05-26 09:09 EDT — messages.13.content.19: Invalid \signature` in `thinking` block` delivered as assistant text to the channel.
  • 2026-05-27 ~16:19 EDT — messages.3.content.19: Invalid \signature` in `thinking` block`, three consecutive messages, before the session-reset safety net broke the cycle and discarded conversation history.

In both cases the bot's user saw a string of API-shaped error text where they were expecting a normal reply. The session-reset that eventually fired also lost the in-conversation memory of an in-progress task (PDF iteration with several deliverables).

Suggested direction (not prescriptive)

Two possible shapes — happy to defer to maintainers on which they prefer or whether something else is better:

A. Filter known-noisy invalid_request_error subtypes to a generic user-facing message ("I had trouble with that request — try again or /new for a fresh session") while preserving the raw text in operator logs. Specifically, the signature-block class of error matches the same THINKING_BLOCK_ERROR_PATTERN introduced for recovery in embedded-agent-runner/thinking.ts; that regex could double as the "this is noise to users" detector here.

B. Default to generic for any invalid_request_error whose raw text contains messages.N.content.M path references — those are API-internal path notation and never user-actionable. Keep the raw passthrough for cleaner messages (e.g. JSON validation that names a field but not an API path).

If neither feels right, this can just be closed — the upstream wiring fix already removed the loop, which was the worst part of the symptom. The remaining leak surface is small.

What I am not proposing

  • Changing the existing test behavior for diagnostic-style invalid_request_error cases (malformed JSON, etc.) — those keep current behavior under either A or B.
  • A channel-side filter. The right layer for this is the formatter, not delivery.
  • Anything about wrapAnthropicStreamWithRecovery — that work is done.

Environment

  • OpenClaw 2026.5.22 (at the time of the production occurrence), now updated to 2026.5.27 on the same install
  • Anthropic provider, claude-sonnet-4-6
  • Telegram channel, single-peer DM

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions