Summary
Sequel to #825, which #826 fixed for provider aliases. A /model <id> that matches neither a configured alias nor a known model family still applies silently, leaving the session on an id no endpoint serves. Suggestion: keep applying it, but say so.
What happened
Real transcript on v0.25.2, immediately after confirming the #826 fix works:
<you> /model low
switched to model: claude-haiku-4-5 · low ← #826, working
<you> /model off
switched to model: off ← applied silently
<you> /model medium
switched to model: claude-sonnet-5 · medium ← recovered
The middle one leaves session.model = "off". Nothing indicates a problem until the next request 400s. Here the user happened to switch again before sending anything.
Why off in particular
off is a valid argument to both /effort off and /agent off. Reaching for /model off to undo a model switch is a natural slip — and there is no /model equivalent of "go back", so the instinct has nowhere else to go.
Not a regression, and please keep it that way
This is the deliberate fallthrough in resolve_model_switch: an id that cannot be classified returns Keep, which is what lets /model claude-opus-6 work the day it ships, before dirge knows the id. #826 narrowed the trap to genuinely unknown strings rather than closing it, on purpose. A whitelist would be the wrong fix.
Suggestion
Warn without refusing. When the id matches no configured provider alias and model_family returns None, still apply it, and add a note.
The condition is already computed in resolve_model_switch — the branch immediately after the alias rule added in #826 — so this is surfacing information, not deriving it.
On what the note may claim. dirge cannot know whether an id is valid; only the provider knows. What dirge knows is whether it recognises it. Those come apart for a new-but-valid id — claude-opus-6 on release day is valid at the provider and unrecognised here — so the note should assert recognition and leave the consequence conditional:
switched to model: off
note: 'off' matches no configured provider alias and no model family dirge
recognises; if your provider does not serve it, the next request will fail
It never fires on the common paths — a configured alias, or an id matching a known family — so in practice it fires on typos and on genuinely new models, where it is still accurate and arguably still useful.
Wording and length are yours to set. The above is deliberately explicit for the issue's sake; something far shorter would carry the same signal, e.g.:
switched to model: off (unrecognised — may not be servable)
I have no attachment to the long form. If you would rather it were a single trailing clause on the existing line, or suppressed behind a flag, say which and I will write it that way.
One alternative, considered and rejected
Suppressing the note when the id "looks like" a model (contains a digit or a hyphen) would keep the success path quiet for claude-opus-6. It is a bad trade:
- A typo that preserves the shape —
claude-opuss-5 — passes silently, which is precisely the case worth catching.
- A legitimately short id (
haiku, o3) draws a spurious note.
- It bakes an assumption about model naming into dirge that providers are under no obligation to honour.
- It adds a rule a reader must know in order to predict the behaviour.
The noise it avoids is not worth having. When the id genuinely is a new model dirge does not know yet, "matches no known model family" is simply true, and a one-line note saying so is information rather than an error.
Happy to submit a PR for the plain always-warn shape if you want it.
Summary
Sequel to #825, which #826 fixed for provider aliases. A
/model <id>that matches neither a configured alias nor a known model family still applies silently, leaving the session on an id no endpoint serves. Suggestion: keep applying it, but say so.What happened
Real transcript on v0.25.2, immediately after confirming the #826 fix works:
The middle one leaves
session.model = "off". Nothing indicates a problem until the next request 400s. Here the user happened to switch again before sending anything.Why
offin particularoffis a valid argument to both/effort offand/agent off. Reaching for/model offto undo a model switch is a natural slip — and there is no/modelequivalent of "go back", so the instinct has nowhere else to go.Not a regression, and please keep it that way
This is the deliberate fallthrough in
resolve_model_switch: an id that cannot be classified returnsKeep, which is what lets/model claude-opus-6work the day it ships, before dirge knows the id. #826 narrowed the trap to genuinely unknown strings rather than closing it, on purpose. A whitelist would be the wrong fix.Suggestion
Warn without refusing. When the id matches no configured provider alias and
model_familyreturnsNone, still apply it, and add a note.The condition is already computed in
resolve_model_switch— the branch immediately after the alias rule added in #826 — so this is surfacing information, not deriving it.On what the note may claim. dirge cannot know whether an id is valid; only the provider knows. What dirge knows is whether it recognises it. Those come apart for a new-but-valid id —
claude-opus-6on release day is valid at the provider and unrecognised here — so the note should assert recognition and leave the consequence conditional:It never fires on the common paths — a configured alias, or an id matching a known family — so in practice it fires on typos and on genuinely new models, where it is still accurate and arguably still useful.
Wording and length are yours to set. The above is deliberately explicit for the issue's sake; something far shorter would carry the same signal, e.g.:
I have no attachment to the long form. If you would rather it were a single trailing clause on the existing line, or suppressed behind a flag, say which and I will write it that way.
One alternative, considered and rejected
Suppressing the note when the id "looks like" a model (contains a digit or a hyphen) would keep the success path quiet for
claude-opus-6. It is a bad trade:claude-opuss-5— passes silently, which is precisely the case worth catching.haiku,o3) draws a spurious note.The noise it avoids is not worth having. When the id genuinely is a new model dirge does not know yet, "matches no known model family" is simply true, and a one-line note saying so is information rather than an error.
Happy to submit a PR for the plain always-warn shape if you want it.