Summary
session_status({"sessionKey":"current"}) can report the wrong model identity because two separate registry/session-resolution problems compound:
"current" can resolve to a legacy per-channel direct session instead of the embedded run's actual live session.
- Even when the correct live session is selected,
session_status reads the cached sessions.json model field, which behaves like a last-run/last-fallback model stamp, instead of lazily resolving the current model intent from modelOverride / agent defaults.
The visible failure mode is that the assistant reports an older/fallback model such as gpt-5.4, while openclaw status and the actual live lane show the current intended model as gpt-5.5.
Environment
- OpenClaw:
2026.5.2 (8b2a6e5)
- Runtime: Node
v22.22.0
- OS: Darwin 25.4.0 arm64
- Channel: Telegram direct embedded agent session
- Live lane provider/model:
openai-codex/gpt-5.5
- Auth mode: Codex OAuth (
openai-codex:<email>)
Registry snapshot
At the time of failure, ~/.openclaw/agents/main/sessions/sessions.json contained multiple session keys for the same agent/user lane:
sessionKey: agent:main:main
sessionId: 5e94482f-…
model: gpt-5.4
modelOverride: gpt-5.5
lastInteractionAt: live/current turn
deliveryContext: { channel: "telegram", to: "telegram:<chat_id>" }
sessionKey: agent:main:telegram:default:direct:<chat_id>
sessionId: c2c4115c-…
model: gpt-5.4
modelOverride: absent
lastInteractionAt: stale / ~30h old
deliveryContext: { channel: "telegram", to: "telegram:<chat_id>" }
sessionKey: agent:main:cron:d6fd5498-…
sessionId: 6a3933bd-…
model: gpt-5.3-codex
modelOverride: absent
lastInteractionAt: recent cron tick
deliveryContext: null
Two important details:
- The legacy
agent:main:telegram:default:direct:<chat_id> entry appears to be a zombie from before the merged-session model. It was stale but still eligible for the "current" alias path.
- The live
agent:main:main entry also had model: gpt-5.4 while modelOverride: gpt-5.5, so even resolving the right session could still return the wrong model identity.
Reproduction
Defect A — "current" resolves to a legacy direct session
- Run OpenClaw
2026.5.2 with agents.list[id="main"].model.primary = "openai-codex/gpt-5.5" and Telegram configured.
- Ensure the session registry contains both:
agent:main:main as the active merged/live session
- a stale
agent:main:telegram:default:direct:<chat_id> legacy session with an older cached model
- From inside the agent, call:
via the session_status tool.
- Observe that
session_status reports the stale legacy direct session's metadata instead of the embedded run's actual live session.
Defect B — the live session's model field is last-run/stamped, not current intent
- Remove or ignore the stale legacy direct session so
"current" resolves to agent:main:main.
- Ensure the live session entry has:
model: gpt-5.4
modelOverride: gpt-5.5
This can happen after a lane fallback: the cached model field is stamped at the model actually used by the most recent completed run.
- Call
session_status({"sessionKey":"current"}) again.
- Observe that the tool reports
gpt-5.4, even though the session's own modelOverride and next intended lane model are gpt-5.5.
Observed behavior
In the live session transcript:
21:38:26 user: "what model are you using"
21:38:29 agent: session_status({"sessionKey":"current"}) -> reports gpt-5.4
21:39:05 user provides openclaw status screenshot showing agent:main:main -> gpt-5.5
21:39:19 agent: session_status({"sessionKey":"current"}) -> still reports gpt-5.4
21:40:54 agent identifies two sessions:
- agent:main:telegram:default:direct:<chat_id> -> gpt-5.4
- agent:main:main -> gpt-5.5
The assistant eventually self-corrected only after comparing explicit session keys. Without user pushback, the session_status tool surface kept reinforcing the wrong answer.
Expected behavior
session_status({"sessionKey":"current"}) should resolve "current" to the session/lane in which the calling embedded run is executing, not to a stale legacy per-channel direct session.
For the model field, the tool should report the current resolved model intent for that session/lane — e.g. modelOverride / agent default resolution — not a cached last-run or last-fallback model value.
If OpenClaw wants to retain last execution metadata, that should be exposed separately, e.g. lastRunModel, rather than overloading model in a way that makes status/introspection lie.
Suggested fix direction
These can land independently:
-
Tie session_status "current" to the running embedded run's session key.
The embedded run already knows the lane/session it is executing in. Pass that through instead of re-running channel/direct lookup.
-
Lazy-resolve current model identity on read.
When session_status reports a session's current model, resolve from the agent config / modelOverride chain at read time. Treat the cached model field as execution history or rename it to lastRunModel.
-
Registry hygiene for legacy direct sessions.
On gateway start, prune or merge stale agent:<id>:<channel>:<account>:direct:<chat_id> entries when agent:<id>:main now owns the same deliveryContext.to.
Local mitigation applied
A local cleanup was applied to confirm the diagnosis:
- Deleted the zombie
agent:main:telegram:default:direct:<chat_id> entry from sessions.json.
- Aligned the live
agent:main:main entry's model with its modelOverride (gpt-5.4 -> gpt-5.5).
This mitigates the local symptom, but it is not an upstream fix. Any user upgraded across the merged-session boundary may still hit Defect A, and any agent that has a lane fail over may still hit Defect B.
Related issues
Summary
session_status({"sessionKey":"current"})can report the wrong model identity because two separate registry/session-resolution problems compound:"current"can resolve to a legacy per-channel direct session instead of the embedded run's actual live session.session_statusreads the cachedsessions.jsonmodelfield, which behaves like a last-run/last-fallback model stamp, instead of lazily resolving the current model intent frommodelOverride/ agent defaults.The visible failure mode is that the assistant reports an older/fallback model such as
gpt-5.4, whileopenclaw statusand the actual live lane show the current intended model asgpt-5.5.Environment
2026.5.2 (8b2a6e5)v22.22.0openai-codex/gpt-5.5openai-codex:<email>)Registry snapshot
At the time of failure,
~/.openclaw/agents/main/sessions/sessions.jsoncontained multiple session keys for the same agent/user lane:Two important details:
agent:main:telegram:default:direct:<chat_id>entry appears to be a zombie from before the merged-session model. It was stale but still eligible for the"current"alias path.agent:main:mainentry also hadmodel: gpt-5.4whilemodelOverride: gpt-5.5, so even resolving the right session could still return the wrong model identity.Reproduction
Defect A —
"current"resolves to a legacy direct session2026.5.2withagents.list[id="main"].model.primary = "openai-codex/gpt-5.5"and Telegram configured.agent:main:mainas the active merged/live sessionagent:main:telegram:default:direct:<chat_id>legacy session with an older cached model{"sessionKey":"current"}via the
session_statustool.session_statusreports the stale legacy direct session's metadata instead of the embedded run's actual live session.Defect B — the live session's
modelfield is last-run/stamped, not current intent"current"resolves toagent:main:main.This can happen after a lane fallback: the cached
modelfield is stamped at the model actually used by the most recent completed run.session_status({"sessionKey":"current"})again.gpt-5.4, even though the session's ownmodelOverrideand next intended lane model aregpt-5.5.Observed behavior
In the live session transcript:
The assistant eventually self-corrected only after comparing explicit session keys. Without user pushback, the
session_statustool surface kept reinforcing the wrong answer.Expected behavior
session_status({"sessionKey":"current"})should resolve"current"to the session/lane in which the calling embedded run is executing, not to a stale legacy per-channel direct session.For the model field, the tool should report the current resolved model intent for that session/lane — e.g.
modelOverride/ agent default resolution — not a cached last-run or last-fallback model value.If OpenClaw wants to retain last execution metadata, that should be exposed separately, e.g.
lastRunModel, rather than overloadingmodelin a way that makes status/introspection lie.Suggested fix direction
These can land independently:
Tie
session_status"current"to the running embedded run's session key.The embedded run already knows the lane/session it is executing in. Pass that through instead of re-running channel/direct lookup.
Lazy-resolve current model identity on read.
When
session_statusreports a session's current model, resolve from the agent config /modelOverridechain at read time. Treat the cachedmodelfield as execution history or rename it tolastRunModel.Registry hygiene for legacy direct sessions.
On gateway start, prune or merge stale
agent:<id>:<channel>:<account>:direct:<chat_id>entries whenagent:<id>:mainnow owns the samedeliveryContext.to.Local mitigation applied
A local cleanup was applied to confirm the diagnosis:
agent:main:telegram:default:direct:<chat_id>entry fromsessions.json.agent:main:mainentry'smodelwith itsmodelOverride(gpt-5.4->gpt-5.5).This mitigates the local symptom, but it is not an upstream fix. Any user upgraded across the merged-session boundary may still hit Defect A, and any agent that has a lane fail over may still hit Defect B.
Related issues
:heartbeat-suffixed session when main session is pruned