openclaw - 💡(How to fix) Fix Dashboard webchat turns can enter message-tool-only mode without a send target

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Dashboard/webchat-originated sessions can enter sourceReplyDeliveryMode: message_tool_only even when there is no external source conversation target for the message tool to infer.

When that happens, the prompt tells the model that visible replies must use message(action="send") and that the target defaults to the current source conversation. In a dashboard-only turn, the dynamic message tool does not have a usable currentChannelId, so message.send fails with:

Action send requires a target.

The assistant can then still produce a normal final answer such as Sent., which is related to the broader fail-closed issue in #49876, but the target-default mismatch here is narrower.

Root Cause

The source reply delivery policy can choose message_tool_only for direct sessions from config or harness defaults without excluding internal dashboard/webchat turns.

For external providers, this is fine because the runtime can pass a source target such as currentChannelId / OriginatingTo. For dashboard-only webchat turns, Provider, Surface, and OriginatingChannel are internal webchat, and there is no external OriginatingTo. The low-level target validator is correct to reject the send; the policy should not have selected message-tool-only delivery for that source in the first place.

Fix Action

Fix / Workaround

  • Detect internal-only webchat sources in resolveSourceReplyDeliveryMode.
  • If the mode would be message_tool_only, coerce it to automatic when there is no external origin/deliver route.
  • Leave message.send target validation unchanged.
  • Add regression coverage for:
    • direct dashboard/webchat turns with global or harness message_tool defaults falling back to automatic
    • webchat routing an external source remaining message_tool_only
    • full dispatchReplyFromConfig dashboard/webchat turn queueing a normal final reply instead of suppressing it

Local validation

I tested this locally with a small patch following the above approach:

pnpm test src/auto-reply/reply/source-reply-delivery-mode.test.ts src/auto-reply/reply/dispatch-from-config.test.ts
# 2 Vitest shards passed: 19 policy tests, 107 auto-reply dispatch tests

Code Example

Action send requires a target.

---

pnpm test src/auto-reply/reply/source-reply-delivery-mode.test.ts src/auto-reply/reply/dispatch-from-config.test.ts
# 2 Vitest shards passed: 19 policy tests, 107 auto-reply dispatch tests

pnpm exec oxfmt --check --threads=1 src/auto-reply/reply/source-reply-delivery-mode.ts src/auto-reply/reply/source-reply-delivery-mode.test.ts src/auto-reply/reply/dispatch-from-config.test.ts
# All matched files use the correct format.

pnpm tsgo:core:test
# passed
RAW_BUFFERClick to expand / collapse

Summary

Dashboard/webchat-originated sessions can enter sourceReplyDeliveryMode: message_tool_only even when there is no external source conversation target for the message tool to infer.

When that happens, the prompt tells the model that visible replies must use message(action="send") and that the target defaults to the current source conversation. In a dashboard-only turn, the dynamic message tool does not have a usable currentChannelId, so message.send fails with:

Action send requires a target.

The assistant can then still produce a normal final answer such as Sent., which is related to the broader fail-closed issue in #49876, but the target-default mismatch here is narrower.

Observed example

In a dashboard session, the user asked the agent to describe its tools. The agent generated a good message(action="send") payload but omitted target, following the prompt guidance. The tool result was Action send requires a target., then the assistant finaled with Sent..

Root cause

The source reply delivery policy can choose message_tool_only for direct sessions from config or harness defaults without excluding internal dashboard/webchat turns.

For external providers, this is fine because the runtime can pass a source target such as currentChannelId / OriginatingTo. For dashboard-only webchat turns, Provider, Surface, and OriginatingChannel are internal webchat, and there is no external OriginatingTo. The low-level target validator is correct to reject the send; the policy should not have selected message-tool-only delivery for that source in the first place.

Proposed fix

Keep automatic final delivery for internal dashboard/webchat-only turns, even if config or a harness default prefers message-tool delivery. Preserve message_tool_only when webchat is merely operating on behalf of an external origin or explicit deliver route.

Concretely:

  • Detect internal-only webchat sources in resolveSourceReplyDeliveryMode.
  • If the mode would be message_tool_only, coerce it to automatic when there is no external origin/deliver route.
  • Leave message.send target validation unchanged.
  • Add regression coverage for:
    • direct dashboard/webchat turns with global or harness message_tool defaults falling back to automatic
    • webchat routing an external source remaining message_tool_only
    • full dispatchReplyFromConfig dashboard/webchat turn queueing a normal final reply instead of suppressing it

Local validation

I tested this locally with a small patch following the above approach:

pnpm test src/auto-reply/reply/source-reply-delivery-mode.test.ts src/auto-reply/reply/dispatch-from-config.test.ts
# 2 Vitest shards passed: 19 policy tests, 107 auto-reply dispatch tests

pnpm exec oxfmt --check --threads=1 src/auto-reply/reply/source-reply-delivery-mode.ts src/auto-reply/reply/source-reply-delivery-mode.test.ts src/auto-reply/reply/dispatch-from-config.test.ts
# All matched files use the correct format.

pnpm tsgo:core:test
# passed

Repo-wide pnpm format:check still reports unrelated pre-existing formatting issues in other files; the three changed files pass oxfmt --check directly.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Dashboard webchat turns can enter message-tool-only mode without a send target