#Main:Main and Telegram Session Have Split

1 messages Ā· Page 1 of 1 (latest)

rapid summit
#

@idle tundra, earlier today, I found an absolutely massive main:main session file had finally closed. It had survived through multiple gateway restarts, new sessions through Telegram, and even a couple of resets through Telegram.

As I tried to figure out what was going on, I noticed this in the list of sessions:

telegram:g-agent-main-telegram-direct-[Telegram ID redacted]
main
heartbeat
webchat:g-agent-main-telegram-direct-[Telegram ID redacted]-heartbeat
Subagent: coder • subagent:55aa5fe3-be9b-4aff-b860-b898a5c2bf42

The Telegram session continues, but the main session that the telegram:g-agent session are not in sync anymore. I can chat with the main session in the web gateway ui chat, but no messages that I send through Telegram go to that session; they only go to this telegram:g-agent session.

So: Should there be a separate telegram session that's divorced from main?

sweet bloomBOT
#

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

idle tundraBOT
#

Short version: yes, that can be expected, but it depends on your session.dmScope.

  • If session.dmScope: "main", Telegram DMs should collapse into the same main session, agent:main:main.
  • If session.dmScope: "per-channel-peer" or "per-account-channel-peer", Telegram gets its own DM session, like agent:main:telegram:direct:<id> or agent:main:telegram:default:direct:<id>, while WebChat/Control UI still defaults to the agent’s main session.

So in that second case, what you’re seeing is normal: Telegram and the Web UI chat are intentionally divorced.

That lines up with current docs, and there’s one extra gotcha: QuickStart/local onboarding now defaults session.dmScope to per-channel-peer when unset, so newer setups often behave exactly like this.

The first thing I’d want from you is:

openclaw --version
openclaw config get session.dmScope

If that comes back as per-channel-peer or per-account-channel-peer, then this split is by design, not corruption.

rapid summit
#

šŸ¦ž OpenClaw 2026.4.15 (041266a) — I'm not saying your workflow is chaotic... I'm just bringing a linter and a helmet.

per-channel-peer

idle tundraBOT
#

Yep, with 2026.4.15 and session.dmScope = per-channel-peer, a separate Telegram DM session is expected.

So in your case:

  • main = the agent’s default WebChat/Control UI session
  • telegram:...direct:... = the Telegram DM session for that peer
  • they will not stay in sync, because they are different session buckets by design

So the answer to your question is basically: yes, in your current config, Telegram should be divorced from main.

That also explains why:

  • chatting in the web gateway UI keeps hitting main
  • chatting from Telegram keeps hitting the Telegram-scoped session instead

If you want Telegram + Web UI to be the same conversation, you’d need session.dmScope: "main" instead. That’s fine for a strictly single-user setup, but less safe for shared/multi-sender inboxes.

#

My read is that the giant old main transcript was just the old/default main bucket hanging around, while Telegram is now correctly routing to its own per-peer channel session.

If you want, I can help you think through which of these is the better fit for your setup:

  1. keep per-channel-peer and accept split UI vs Telegram sessions
  2. switch to main so Telegram and Web UI share one thread
rapid summit
#

I'm the only person interacting with Jeeves (my main agent). If I set others up, they will be interacting with a different agent, not Jeeves.

idle tundraBOT
#

Yeah, in that case I’d probably switch Jeeves to session.dmScope: "main".

Because for your setup:

  • one human
  • one agent
  • other people would use different agents anyway

…per-channel-peer doesn’t buy you much, and it creates exactly the split you’re seeing between Telegram and the Web UI.

So I’d frame it like this:

  • per-channel-peer: correct if you want Telegram and Web UI to stay separate
  • main: better if you want ā€œJeeves is one brain no matter where I talk to himā€

One important nuance: if you switch back to main, it won’t magically merge the old Telegram-scoped transcript into main. It just means future Telegram messages should route back into the main session bucket.

#

So, short answer: for your use case, I think main is the better fit.

rapid summit
#

OK. So once I make that change in openclaw.json and restart the gateway, what else, if anything, do I need to do to make sure that this config change takes effect cleanly?

idle tundraBOT
#

Pretty minimal, actually.

After you change session.dmScope to main and restart the gateway, I’d do this:

  1. Send one fresh message from Telegram

    • that should now route to the main session bucket
  2. Check the sessions list

    • confirm new turns are landing in main
    • the old Telegram-scoped session may still exist as an old transcript, which is fine
  3. Optionally run /new once

    • only if you want a clean shared session going forward
    • do this after the config change, not before

A couple of useful notes:

#
  • You do not need to delete the old Telegram session file for the change to work.
  • Old Telegram-specific history will not merge into main; it just becomes old history.
  • If you have any heartbeat/cron/session-targeted config explicitly pinned to the old Telegram session key, update that too. If not, nothing extra there.

So the short answer is: restart is usually enough, then verify with one Telegram message.
If you want the switch to feel extra clean, do a single /new after the restart.

Docs:

Glad we tracked this down, this one’s subtle.

rapid summit
#

Got it. Thanks. Out of curiosity, when did this dmScope change occur? I've had a lot of weird behavior for a few days that is explained by the session split—Jeeves in Telegram would check what model he was using in main:main, and it would come back different from what Telegram was showing. Those problems cleared up today when the main session finally rotated (after 10 days!).

idle tundraBOT
#

I checked the changelog, and the big one is:

  • 2026.2.21: breaking change: local CLI onboarding started setting session.dmScope to per-channel-peer by default when it was previously unset.

Then there was a follow-up:

  • 2026.2.26: a DM-scope migration fix landed to retire stale main-session delivery metadata once the direct peer session becomes active.

So my read is:

  • this probably did not first change in 2026.4.15
  • the actual behavior shift likely happened whenever your config picked up session.dmScope: "per-channel-peer"
  • the weirdness only became obvious because that old main session kept limping along for days, then finally rotated out today

And yeah, your ā€œTelegram checks model in main:main and gets a different answerā€ example fits the split-brain story really well.

So the short version is:

#
  • feature/default change: 2026.2.21
  • cleanup/follow-up migration fix: 2026.2.26
  • your local exact moment: whenever openclaw.json got that dmScope line

That’s a sneaky one. I’m glad the session rotation finally made the pattern visible.

rapid summit
#

One last question: After I make the configuration change, restart the gateway, start a new session, send a message from Telegram, and (hopefully) see that message show up in the web chat, what happens to the session "webchat:g-agent-main-telegram-direct-[Telegram ID redacted]-heartbeat"?

Does that keep going, with the heartbeat staying unsynced? Or does it just go stale, and a new heartbeat session that's synced shows up the next time heartbeat fires?

idle tundraBOT
#

Most likely, the old ...-heartbeat session just goes stale, and the next heartbeat run creates/uses a new heartbeat session tied to the new base session.

In other words, after you switch back to dmScope: "main":

  • if heartbeat is targeting main (the default), the next isolated heartbeat run should hang off main, not the old Telegram-scoped session
  • the old webchat:g-agent-main-telegram-direct-...-heartbeat entry should just sit there as old history until session cleanup prunes it

Two important caveats:

  • If you have heartbeat.session explicitly pinned to that old Telegram-scoped session, then yes, it would keep staying unsynced until you change/remove that pin.
  • If heartbeat.isolatedSession is false, then you won’t get a separate ...-heartbeat session at all. The separate heartbeat session only exists when isolation is on.

So the quick sanity check is:

  • heartbeat.session unset or main → you’re fine, next heartbeat should follow the synced/main world
  • heartbeat.session = old Telegram session key → update that too
rapid summit
#

All working. Thanks!

idle tundraBOT
#

Nice, glad it’s behaving again 🦐

If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
That helps Answer Overflow index it for the next person who hits the same weird split-session bug.