#Telegram outbound routing silently breaks after gateway restart — replies go to TUI instead of Teleg

1 messages · Page 1 of 1 (latest)

untold forum
#

We've been hitting a recurring issue across v2026.3.8, 3.12, and now 3.13 where Telegram outbound delivery silently stops working after a gateway restart (whether from config.patch, update.run, or manual gateway restart).

What happens:

• Inbound Telegram messages are received normally (polling works fine)
• Agent processes the message and generates a reply
• But the reply goes to the TUI/webchat instead of Telegram — the user never receives it
• openclaw status shows Telegram: ON, state: OK (no error reported)
• The message tool with explicit channel: telegram still works — only session routing is broken
• No sendMessage entries in gateway.log after the restart

Pattern observed:

• Sometimes breaks immediately after restart
• Sometimes works for 20-30 minutes then silently stops
• Only fix: gateway restart (which sometimes re-triggers the bug)
• We've had 5+ occurrences in the past week

Environment:

• macOS, Telegram long-polling mode (no webhook)
• Single bot, single user (allowFrom configured)
• Versions affected: 2026.3.8, 2026.3.12, 2026.3.13

Possibly related to: #28622 (health-monitor doesn't detect dead Telegram polling) and the 3.12 fix "Gateway/main-session routing: keep TUI and other mode:UI main-session sends on the internal surface when deliver is enabled" (#43918) — which partially helped but didn't fully resolve it.

Workaround: gateway restart — but it's unreliable since the restart itself can trigger the same bug.

Happy to provide logs or additional details if needed. Thanks!

covert brambleBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

exotic crowBOT
#

This smells like a main-DM session routing (session.dmScope) + lastRoute edge case, not “Telegram can’t send”.

When DMs collapse to the agent’s main session (session.dmScope: "main"), outbound delivery for that session can end up following whatever the session thinks the last route was (often webchat/TUI after a restart), so you’ll see the reply in the UI and no sendMessage at all in logs. The fact that the message tool with channel: telegram still works strongly suggests Telegram is fine and it’s the session → route resolution that’s wrong.

Fastest workaround to try (usually fixes this class of issue)

Set DM sessions to not share the main key:

// ~/.openclaw/openclaw.json
{
  session: {
    dmScope: "per-channel-peer", // (or per-account-channel-peer if you use multiple telegram accounts)
  },
}

Restart the gateway after changing it. This makes Telegram DMs use a dedicated session key (so WebChat/TUI can’t “steal” the route for that DM). Docs: https://docs.openclaw.ai/concepts/session and https://docs.openclaw.ai/channels/channel-routing

#

If you want to debug it properly (and get a solid bug report)

When it’s “broken”, can you paste redacted outputs of:

  1. openclaw --version
  2. openclaw gateway status (this catches config/state-dir mismatches after restarts)
  3. openclaw status --all
  4. The relevant entry from the session store:
    • ~/.openclaw/agents/<agentId>/sessions/sessions.json
    • Look for the session key you’re actually using (often agent:main:main when dmScope=main)
    • Specifically: what does it show for lastRoute / origin (does it say webchat when you expected telegram?)

If lastRoute is indeed stuck on webchat after a Telegram inbound, that’s the smoking gun.

If switching dmScope to per-channel-peer doesn’t stop it, it’s very likely a real regression in route persistence/update after restart — at that point I’d strongly recommend filing a GitHub issue with the 4 items above + a small log window around a restart + first broken inbound.

untold forum
# exotic crow ### If you want to debug it properly (and get a solid bug report) When it’s “bro...

Hey Krill, thanks for the detailed response! Here's the info you asked for:

Version: OpenClaw 2026.3.13 (61d171a)

Setup:

• macOS 26.1 (arm64), Mac Studio
• Channels: Telegram (DM, allowlist) + Discord + TUI (occasional)
• Gateway: local loopback, LaunchAgent, pid running
• Model: claude-opus-4-6

The problem:
After a gateway restart, Telegram DM replies sometimes vanish — no error in logs, agent processes the message, but the reply never arrives on Telegram. It happens intermittently, especially after using the TUI or after a restart.

What I found in sessions.json:

The agent:main:main session has origin pointing to Telegram, but there are also 4 TUI sessions with origin webchat. With dmScope: "main" (default), both Telegram DM and TUI share agent:main:main. After a restart, if the TUI reconnects first, lastRoute can get stuck pointing at webchat → replies go there instead of Telegram.

Fix applied:
Set session.dmScope: "per-channel-peer" so Telegram DM gets its own isolated session and TUI can't steal the route.

Will report back if it resolves the issue or if it persists. Thanks for pointing us to the session routing docs! 🙏

exotic crowBOT
#

That lines up perfectly with how DM routing works today.

With session.dmScope: "main", Telegram DM + WebChat/TUI all share agent:main:main, so after a restart whichever surface reconnects first can “win” lastRoute. If that ends up being webchat, you’ll get exactly what you saw: agent run completes, but no Telegram sendMessage call ever happens because the outbound route resolution never targets Telegram.

Switching to:

session: { dmScope: "per-channel-peer" }

is the right mitigation (and it’s also what the security docs recommend for deterministic isolation). Quick sanity check after the change:

  • Telegram DM session key should look like agent:main:telegram:direct:<yourId>
  • WebChat/TUI should be agent:main:webchat:direct:<something>
  • agent:main:main should stop being involved in Telegram DMs entirely

If this still happens with per-channel-peer, then it’s almost certainly a different bug (not just lastRoute getting stolen) — in that case, grabbing the broken-session entry + a short gateway.log window around the inbound DM would be enough to file a tight GitHub issue.