Skip to content

[Bug]: Nextcloud Talk channel agent silently skips message tool, marks reply 'completed' without posting #76980

Description

@marfrit

Bug type

Behavior bug (agent fails to deliver reply, no error)

Summary

In the @openclaw/nextcloud-talk channel, the embedded agent harness inconsistently calls the message tool to deliver replies back to Nextcloud Talk. When it doesn't, the agent streams generated text via the text_end channel — which is a no-op for the nextcloud-talk plugin's deliveryMode: "direct" outbound config — then logs a message processed: outcome=completed diagnostic. From the operator's perspective the run looks successful, but no chat message ever lands in Nextcloud.

Webhook ingress, signature verification, OpenRouter/LLM call, agent reasoning, session-state housekeeping all work. Only the outbound back-to-NC step is silently dropped.

Environment

  • OpenClaw 2026.5.2 (8b2a6e5) — installed via npm install -g openclaw on Debian 13 trixie LXD container, aarch64
  • Plugin @openclaw/[email protected] — installed via openclaw plugins install
  • Node 22.22.2 (NodeSource, aarch64)
  • Nextcloud 33.0.0, spreed (Talk app) 23.0.3
  • Bot installed with --feature webhook --feature response --feature reaction
  • Channel config: groupPolicy: open, rooms."*".requireMention: false, network.dangerouslyAllowPrivateNetwork: true, agents.defaults.model: openrouter/openrouter/auto
  • LLM provider: OpenRouter (autoselect)

Reproduce

  1. Fresh install OpenClaw + nextcloud-talk plugin per docs.
  2. Configure channel: baseUrl, botSecretFile, groupPolicy=open, rooms."*".requireMention=false, network.dangerouslyAllowPrivateNetwork=true (we're on a LAN-internal Nextcloud whose DNS resolves to 192.168.x.x).
  3. Configure OpenRouter provider with models.providers.openrouter.{baseUrl, apiKey, models:[{id:"openrouter/auto",api:"openai-completions"}]}, agents.defaults.model = "openrouter/openrouter/auto".
  4. occ talk:bot:install OpenClaw <secret> http://<heisenberg-ip>:8788/nextcloud-talk-webhook --feature webhook --feature response --feature reaction
  5. occ talk:bot:setup <bot-id> <room-token>
  6. Send a chat message in the room.

Observed

  • Webhook arrives, signature verifies, run starts.
  • LLM call completes; embedded run agent end: isError=false.
  • Log line: [agent/embedded] Skipping message_end safety send for text_end channel - content already delivered via text_end
  • Log line: Delivery suppressed by sourceReplyDeliveryMode: message_tool_only for session ... — agent will still process the message
  • No tool=message invocation in logs.
  • Log line: [diagnostic] message processed: channel=nextcloud-talk ... outcome=completed duration=XXXXms
  • Nothing reaches Nextcloud. oc_comments for the room shows only the user's message; no bot reply.

On the very FIRST run after a clean session reset (delete <sessionId>.jsonl, <sessionId>.trajectory.jsonl, scrub the entry from sessions.json, restart openclaw.service), the agent does call the message tool and the reply lands. The bot post appears in oc_comments as expected. Subsequent messages in the same session revert to the text_end-streamed-into-void behavior.

Expected

For a channel with outbound.base.deliveryMode: "direct" (which the nextcloud-talk plugin sets at src/channel.ts:169), every reply should either:

  • result in a tool=message invocation that calls sendMessageNextcloudTalk, or
  • log a clear failure if the agent decided not to reply (e.g., "agent declined to reply" with a reason),

but never silently mark outcome=completed after streaming text into a sink that the channel doesn't consume.

Suspect locations

  • @openclaw/nextcloud-talk src/channel.ts:163-185 — sets outbound.base.deliveryMode: "direct" and provides sendText adapters, but doesn't appear to wire the text_end streaming path to anything.
  • Core dist/plugin-sdk/src/auto-reply/...sourceReplyDeliveryMode = "message_tool_only" is inferred from the channel's deliveryMode: "direct", but the agent harness then doesn't always honor it.
  • The agent appears to learn from prior failed tool=message results in the persisted session/trajectory (we hit a SsrfBlockedError on first attempt before adding dangerouslyAllowPrivateNetwork; afterwards the agent stopped calling the tool entirely until the session was wiped).

Workaround

Delete the session's *.jsonl + *.trajectory.jsonl + the corresponding entry in sessions.json, then restart the gateway. First reply after restart usually goes through, subsequent ones may not.

Logs (representative slice — successful first reply, then failed second)

# Successful run after session wipe (msg #99 actually posted):
22:31:46 [diagnostic] message queued: source=dispatch
22:31:51 [diagnostic] message processed: outcome=completed duration=XXXXms
# (bot reply landed in oc_comments at this point)

# Subsequent run (msg #100 — silently dropped):
22:34:33 Delivery suppressed by sourceReplyDeliveryMode: message_tool_only ... — agent will still process the message
22:34:34 [agent/embedded] embedded run prompt start: provider=openrouter api=openai-completions ...
22:34:44 [agent/embedded] embedded run agent end: runId=6bb3dd3a-... isError=false
# NO tool=message log line for this run.
22:34:44 [diagnostic] message processed: channel=nextcloud-talk chatId=nextcloud-talk:wnvy5gd9 messageId=100 outcome=completed duration=10808ms
# Nothing in Nextcloud's oc_comments table for this message.

Related

Possibly the same root cause as #34111 (closed stale, no resolution) but with a much sharper repro: webhook + signature + LLM all confirmed working, the failure is exclusively in the agent → outbound-tool path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request 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:message-lossChannel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.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