Telegram topic lane strands queued messages after a blocked Bash tool call (claimed, attempts=0, never dispatched)
Environment
- openclaw 2026.9.2 (3928bad)
- Node 22.23.2, Debian 12, SQLite 3.40.1
- Telegram channel, forum group with topics; gateway run under a leader-gate wrapper
Summary
After a turn ends while a Bash tool call is outstanding, the affected per-topic lane can stop dispatching. Subsequent inbound messages are written to channel_ingress_events with status='claimed' and attempts=0, and then never attempted. The claim is taken once and not renewed, and no worker picks the row up. From the user's side the bot shows a typing indicator and never replies.
Other lanes are unaffected. The gateway itself stays healthy throughout: it accepts new websocket connections, answers cron list, and logs no event-loop stalls. Only the one lane is stranded.
Restarting the gateway clears it, and the stranded rows then complete normally.
Observed sequence
- A turn in one topic runs a
Bashtool call. diagnosticbegins emitting, every 30s:
stalled session: sessionId=<uuid> sessionKey=agent:main:telegram:group:<chat>:topic:<topic>
state=idle queueDepth=1 reason=blocked_tool_call classification=blocked_tool_call
activeWorkKind=tool_call lastProgress=tool:Bash:started lastProgressAge=194s
activeTool=Bash activeToolCallId=<id>
Note state=idle together with activeWorkKind=tool_call.
- The tool call ends. I sampled the agent process tree three times at 20s intervals and found no child processes at all, so nothing was still running. The stall lines also stop.
- A new inbound message for that topic is accepted and written as
claimed,attempts=0,claim_owner= the live gateway pid (not a stale owner from a previous process). claimed_atis not refreshed on subsequent polls, andattemptsnever increments. The row simply sits there.
Evidence
Two occurrences on the same day, same topic, both preceded by a blocked Bash call. Delay is time from receipt to completion, where completion only happened after a gateway restart:
| received (UTC) | attempts | delay to completion |
|---|---|---|
| 01:43:47 | 0 | 1,126 s |
| 01:45:50 | 1 | 3,745 s |
| 01:54:30 | 2 | 5,193 s |
| 02:09:03 | 0 | 4,369 s |
| 02:20:59 | 0 | 3,747 s |
| 05:02:01 | 0 | 621 s |
Between 04:29 and 05:02 no other message arrived on any Telegram lane, so the second occurrence is a single stranded row rather than a general backlog.
Ruled out
- Stale claim from a dead process.
claim_ownermatched the running gateway pid. - A hung child process. No descendants of the agent process existed while the row sat unattempted.
- Gateway unresponsiveness. Handshakes succeeded throughout at ~2 s, and no
liveness heartbeat delayedentries were logged during the second occurrence. - Database contention. Hot queries on the state DB run in 2–4 ms in isolation; plans use their indexes; the slow-transaction rate is flat across the whole day and does not correlate with these events.
Impact
A topic goes silent while appearing to be working, because the typing indicator stays on. The only remedy I found is a full gateway restart, which is heavy: it drops every in-flight turn across all lanes to recover one.
Possible direction
The combination state=idle + activeWorkKind=tool_call looks like the lane's in-memory busy flag outliving the work it was tracking, so the dispatcher never considers the lane free again while the queue layer keeps handing it claims. Two things that would help operationally regardless of the root cause:
- Release or re-queue a claim that has not been attempted within its lease, rather than holding it indefinitely.
- Let the existing
blocked_tool_calldetector, which already notices this within 30 seconds, clear or fail the lane after a bound instead of only reporting it.
Happy to gather more detail from a live occurrence if there is specific instrumentation that would help.
Source: openclaw/openclaw