Once you switched a session model, you could not switch back — now /model reset returns it to the default


Last week you tried a new model. You typed /model, switched, used it for ten minutes, and then wanted your old model back. You edited the default in config.yaml, restarted the gateway — and the session was still running on the new model. In the end you ran /new and watched two days of context disappear.

That is not a caching bug. The switch you made inside the session is a pin stored on the session: it is written to the session store (and to the session row on Desktop), and it outranks anything you change in the default afterwards. The only way to pull that pin out used to be starting a new session — at the cost of the history.

Three layers of model config, and which one wins

To see why, look at where a model actually comes from. There are three layers:

  1. model.default in config.yaml — the global default, the layer you normally edit.
  2. channel_overrides — a model set per channel or chat, which outranks config.yaml.
  3. The session override — the model you switched to with /model in one conversation. Highest priority, and persisted.

The persistence is the trap. It is not just an in-process variable: after a restart, session restore brings it back, and editing config.yaml does nothing because the session layer is read first. The result is the confusing state where the config clearly says model A and the session keeps running model B.

The only escape was /new: a fresh session has no pin, so it falls back to the default. The price was the context.

/model reset: pull the pin, keep the history

The newly merged /model reset closes that gap. With no arguments it does one specific thing: clears this session’s model override so the session resolves its model again through channel overrides and then config.yaml — with the transcript intact.

The surfaces differ slightly in mechanics but agree in meaning:

Surface What it does
Messaging gateway (Telegram, Discord, Slack, …) Clears the in-memory override, the persisted override, and any armed --once restore; evicts the cached agent so the next turn is built from the default route; leaves a next-turn model note so the model does not keep identifying as the old one
TUI gateway / Desktop (config.set model) Drops the pin and the one-turn restore, adopts config.yaml through the config-sync switch without writing a new pin, and persists the session row so session.resume cannot resurrect the old pin
Classic CLI Reads config.yaml fresh (no cache) for the current default; if there is no model.default, it says there is nothing to go back to

The success message states exactly what happened instead of a vague “switched”:

Session model override cleared — now using `provider/your-default-model` (the channel/global default). Conversation history kept.

And when there was no pin, it does not pretend otherwise:

No session model override is active — already using `provider/your-default-model` (the channel/global default).

The CLI has its own copy for two edge cases: already on the configured default (“nothing to reset”), and no model.default in config.yaml (“nothing to reset to”).

Rules worth knowing

No flags allowed. Anything after /model reset is rejected, with a message that says why: “/model reset takes no flags — it clears this session’s model override so the configured default applies again.” To switch to a specific model use /model <name>; to change the global default use --global. Do not mix the two in one command.

It is not an alias for default. /model default keeps its old meaning (MoA has a preset literally named default), which is why reset was made a separate request type rather than “switch to a model called default”. If one of your model ids really is reset, the qualified form (vendor/reset or vendor:reset) still reaches it.

“Default” may not be what is in config.yaml. Resolution goes through channel overrides first, so inside that chat /model reset returns to the model the channel is supposed to use. If you configured a model for one group, that is expected behavior — per-chat model overrides explains the full precedence chain.

It does not touch your config. /model reset only changes the session layer. To change the global default, use /model <name> --global or edit config.yaml. Keeping the two separate is what stops an experiment from silently becoming everyone’s default.

When it earns its keep

  • Trying models: switch, compare a couple of turns, reset back — no new session required.
  • A mistaken --once: the one-turn model is supposed to last one turn; if it got stuck, reset clears that armed restore too.
  • Debugging someone else’s session: when “I changed the config and nothing happened”, reset once and see which model it actually runs.
  • After changing providers: pull the old pin out so the new routing can take effect.

On status, plainly: /model reset merged on 2026-11-01 (PR #80448) and shipped in v0.22.6 (2026-11-02), so a normal upgrade gets it; v0.22.5 and older do not have the command.

Related reading: how to declare context windows and capabilities when the model catalog is wrong — the model_overrides guide; how compression and approvals run on a separate model lane — the auxiliary model lane; the full argument list — hermes model command reference.