Skip to content

[Bug]: session_status leaks stale model identity via current alias and cached last-run model #76772

@sene1337

Description

@sene1337

Summary

session_status({"sessionKey":"current"}) can report the wrong model identity because two separate registry/session-resolution problems compound:

  1. "current" can resolve to a legacy per-channel direct session instead of the embedded run's actual live session.
  2. 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

  1. Run OpenClaw 2026.5.2 with agents.list[id="main"].model.primary = "openai-codex/gpt-5.5" and Telegram configured.
  2. 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
  3. From inside the agent, call:
{"sessionKey":"current"}

via the session_status tool.

  1. 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

  1. Remove or ignore the stale legacy direct session so "current" resolves to agent:main:main.
  2. 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.

  1. Call session_status({"sessionKey":"current"}) again.
  2. 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:

  1. 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.

  2. 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.

  3. 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:

  1. Deleted the zombie agent:main:telegram:default:direct:<chat_id> entry from sessions.json.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions