Skip to content

[Bug]: Discord /model picker shows stale model after hot-reloaded default switch #104614

Description

@compoodment

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

On 2026.7.1-beta.5, the Discord /model picker can show a stale current model after the default model changes and hot-reloads successfully. In the observed case, openclaw models status and a no-override direct agent run both proved the agent default was openai/gpt-5.6-terra, but the Discord picker still displayed the current model as gpt-5.5.

A related picker interaction also produced the ephemeral notice:

Sorry, that model isn't available anymore.

That notice came from the Discord picker path, not from the model runner. The model itself was available and runnable through the Codex harness.

Steps to reproduce

Observed on a live Discord DM agent:

  1. Run OpenClaw 2026.7.1-beta.5 (b6387af) with Discord enabled and the bundled codex plugin enabled.
  2. Use OpenAI/Codex OAuth so openai/gpt-* routes through the Codex harness.
  3. Start with default model openai/gpt-5.5.
  4. Add newer Codex models to the configured agent model allowlist, for example:
{
  "agents": {
    "defaults": {
      "models": {
        "openai/gpt-5.6-luna": { "alias": "luna" },
        "openai/gpt-5.6-terra": { "alias": "terra" },
        "openai/gpt-5.6-sol": { "alias": "sol" }
      }
    }
  }
}
  1. Change the default model through the supported CLI path:
openclaw models set terra
  1. Confirm the gateway hot-reloads and model status reports Terra:
openclaw models status --json

Observed status excerpt:

{
  "defaultModel": "openai/gpt-5.6-terra",
  "resolvedDefault": "openai/gpt-5.6-terra",
  "aliases": {
    "luna": "openai/gpt-5.6-luna",
    "terra": "openai/gpt-5.6-terra",
    "sol": "openai/gpt-5.6-sol"
  },
  "allowed": [
    "ollama-cloud/kimi-k2.5:cloud",
    "ollama-cloud/glm-5.2",
    "openai/gpt-5.5",
    "openai/gpt-5.6-luna",
    "openai/gpt-5.6-terra",
    "openai/gpt-5.6-sol"
  ]
}
  1. Prove a no-override agent run uses Terra:
openclaw agent \
  --agent main \
  --session-key agent:main:model-smoke-default-terra-20260711 \
  --message "Reply with exactly: DEFAULT_TERRA_OK" \
  --json \
  --timeout 240

Observed result excerpt:

{
  "status": "ok",
  "text": "DEFAULT_TERRA_OK",
  "provider": "openai",
  "model": "gpt-5.6-terra",
  "harness": "codex",
  "fallbackUsed": false
}
  1. Open the Discord /model picker in the DM.

Expected behavior

The Discord /model picker should reflect the current selected/default model after a hot-reloaded default model change.

In this case, after openclaw models set terra, the picker should show openai/gpt-5.6-terra as current/default, or otherwise clearly distinguish selected vs effective model if those are intentionally different.

If an older picker message was generated before the model change, interacting with it should produce a refresh/expired-picker message that tells the user to reopen /model, not "that model isn't available anymore" when the model is actually available.

Actual behavior

The Discord picker still displayed the current model as gpt-5.5 even though:

  • openclaw models status --json reported defaultModel and resolvedDefault as openai/gpt-5.6-terra.
  • A no-override direct agent run used provider openai, model gpt-5.6-terra, harness codex, with no fallback.
  • The gateway log showed config hot reload applied for agents.defaults.model.primary.

Earlier in the same repro session, selecting Terra through the picker produced:

Sorry, that model isn't available anymore.

OpenClaw version

OpenClaw 2026.7.1-beta.5 (b6387af)

Operating system

Ubuntu VPS

Install method

User-local npm global install, managed by openclaw-gateway.service as a systemd user service.

Model

  • Previous default: openai/gpt-5.5
  • New default: openai/gpt-5.6-terra
  • Also configured/allowed: openai/gpt-5.6-luna, openai/gpt-5.6-sol

Provider / routing chain

OpenAI provider model refs through the bundled Codex app-server harness:

  • provider: openai
  • model: gpt-5.6-terra
  • harness: codex
  • fallback used: false

Additional provider/model setup details

The CLI paths understood the alias correctly:

openclaw models set terra

resolved and persisted:

Default model: openai/gpt-5.6-terra

The failure appears specific to the Discord picker display/interaction state, not to model availability or runtime routing.

Logs, screenshots, and evidence

Gateway hot reload evidence:

[reload] config change detected; evaluating reload (agents.defaults.model.primary, meta.lastTouchedAt)
[reload] config hot reload applied (agents.defaults.model.primary)

The exact "not available anymore" string is present in the installed Discord picker handler in dist/provider-JveWbP3C.js around the parsed.action === "model" path. That path resolves the selected model from the interaction and checks it against freshly loaded picker data before showing:

Sorry, that model isn't available anymore.

Possible clue: the agent-local models.json file on the host was stale/empty while the live config/status/direct-run paths were correct. I did not prove that file is the root cause, but it may be worth checking whether Discord picker data can read stale catalog/session state after a hot reload.

Related issues

This seems related but not identical to existing model-state issues:

This report is specifically about the Discord /model picker showing stale current model state and/or rejecting an actually available model after a hot-reloaded default switch.

Impact and severity

Moderate UX/operational correctness bug. The model can be running correctly while the Discord picker tells the user the old model is current or that the new model is unavailable. That sends operators toward provider/auth debugging even though the runner and config are healthy.

Additional information

Workaround: use canonical model refs or the CLI-supported setter path, then trust /status / models status / actual run metadata over the Discord picker until the picker is refreshed or fixed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.no-staleExclude from stale automation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions