openclaw - 💡(How to fix) Fix [Bug]: Google Chat: reply chunks 2+ land as top-level messages instead of staying in thread [1 participants]

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…
GitHub stats
openclaw/openclaw#70041Fetched 2026-04-23 07:30:04
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
labeled ×2

When an agent reply exceeds 4 000 characters and is split into multiple chunks, only the first chunk stays in the original message thread. All subsequent chunks are posted as new top-level messages in the space.

But short replies (under 4 000 chars, single chunk) always thread correctly.

Root Cause

Root cause

The agent runner initialises currentMessageId from the inbound context's MessageSidFull ?? MessageSid, which is the Google Chat message resource name (e.g. spaces/X/messages/MSG_ID).

Fix Action

Fix / Workaround

Workaround

In channel.runtime-*.js (Google Chat), override replyToId in the deliver callback with the thread name from the inbound context before it reaches the delivery function:

RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When an agent reply exceeds 4 000 characters and is split into multiple chunks, only the first chunk stays in the original message thread. All subsequent chunks are posted as new top-level messages in the space.

But short replies (under 4 000 chars, single chunk) always thread correctly.

Steps to reproduce

  1. Configure a Google Chat group space with a working OpenClaw bot.
  2. Send a message that produces an agent reply longer than 4 000 characters.
  3. Observe that chunk 1 appears correctly as a reply in the thread, but chunks 2+ appear as new top-level messages.

Expected behavior

For a message to openclaw in gchat, all subsequent replies should be under the same thread unless the user starts a new message at the top level.

Actual behavior

Openclaw immediately posts a typing indicator "<Bot> is typing..." replying to the user's message. The first chunk streamed back by the gateway updates the typing indicator to the text message. But if the message exceeds the chunk character limit, subsequent blocks get posted as top level messages in the space, rather than under the same thread.

Example:

[User] Write me a detailed report on...

[OpenClaw]  ← in thread (typing message, edited to chunk 1)
  Here is the report... [first 3,000 chars]

[OpenClaw] ← top-level, outside thread [next 3,000 chars...]

[OpenClaw] ← top-level, outside thread [final 3,000 chars...]

OpenClaw version

v2026.4.15

Operating system

Ubuntu 24.04

Install method

installer script (curl -fsSL https://openclaw.ai/install.sh | bash)

Model

qwen3.6-plus

Provider / routing chain

openclaw ->

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

Google chat users who are using openclaw as an App integration, with service role configured.

Frequency = always .

Additional information

Root cause

The agent runner initialises currentMessageId from the inbound context's MessageSidFull ?? MessageSid, which is the Google Chat message resource name (e.g. spaces/X/messages/MSG_ID).

currentMessageId: params.sessionCtx.MessageSidFull ?? params.sessionCtx.MessageSid, This value flows through createBlockReplyDeliveryHandler as the fallback replyToId on block reply payloads:

replyToId: payload.replyToId ?? (payload.replyToCurrent === false ? void 0 : params.currentMessageId) // = "spaces/X/messages/MSG_ID" ← message name, not thread name In deliverGoogleChatReply, chunks 2+ are sent with:

await sendGoogleChatMessage({ space, text: chunk, thread: payload.replyToId }) // thread = "spaces/X/messages/MSG_ID" Google Chat's spaces.messages.create API expects thread.name to be a thread resource name (spaces/X/threads/T_ID). A message name is not a valid thread reference — Google silently ignores it and creates a new top-level message.

Chunk 1 is unaffected because it calls updateGoogleChatMessage on the typing-indicator placeholder (which is already in the correct thread) and never consults replyToId.

The correct thread name is available in the inbound context as ReplyToId (message.thread?.name), but the agent runner does not use it for currentMessageId.

Workaround

In channel.runtime-*.js (Google Chat), override replyToId in the deliver callback with the thread name from the inbound context before it reaches the delivery function:

// In processMessageWithPipeline, deliver callback: deliver: async (payload) => { await deliverGoogleChatReply({ payload: { ...payload, replyToId: ctxPayload.ReplyToId ?? payload.replyToId }, // ctxPayload.ReplyToId = message.thread?.name = "spaces/X/threads/T_ID" This keeps all chunks in the correct thread.

extent analysis

TL;DR

To fix the issue of subsequent chunks being posted as new top-level messages, update the replyToId in the deliver callback to use the correct thread name from the inbound context.

Guidance

  • The root cause is the incorrect use of MessageSidFull or MessageSid as the replyToId, which is a message resource name, instead of the thread resource name.
  • To verify the fix, send a message that produces an agent reply longer than 4,000 characters and check if all chunks are posted under the same thread.
  • Update the deliver callback in channel.runtime-*.js to override replyToId with the correct thread name from the inbound context.
  • The correct thread name is available in the inbound context as ReplyToId (message.thread?.name).

Example

// In processMessageWithPipeline, deliver callback:
deliver: async (payload) => {
    await deliverGoogleChatReply({
        payload: { ...payload, replyToId: ctxPayload.ReplyToId ?? payload.replyToId },
        // ctxPayload.ReplyToId = message.thread?.name = "spaces/X/threads/T_ID"

Notes

This fix assumes that the ReplyToId in the inbound context is correctly set to the thread resource name. If this is not the case, further investigation may be needed to determine the correct thread name.

Recommendation

Apply the workaround by updating the deliver callback in channel.runtime-*.js to use the correct thread name from the inbound context. This will ensure that all chunks are posted under the same thread.

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…

FAQ

Expected behavior

For a message to openclaw in gchat, all subsequent replies should be under the same thread unless the user starts a new message at the top level.

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 [Bug]: Google Chat: reply chunks 2+ land as top-level messages instead of staying in thread [1 participants]