Preflight Checklist
What's Wrong?
An unrecognized slash command used to be rejected locally, for free, with a fixed error string.
As of 2.1.273 it instead routes through the model via a new unknown_command_fallback
attachment kind, at a real cost. Between 2.1.273 and 2.1.274, the cost for the identical input
rose roughly 20-27x, and kept varying a lot run to run on the same build:
| Version |
Handling |
Observed cost |
Reply shape |
| pre-2.1.273 |
Rejected locally |
$0 |
Fixed literal, e.g. Unknown command: /some-command |
| 2.1.273 |
Routed to the model |
$0.000951 (one measurement) |
Short fallback line |
| 2.1.274 |
Routed to the model, same mechanism |
$0.00917, $0.023845, $0.0212, $0.02302, $0.020645, $0.025795, $0.1234 (seven measurements, same session, same unflagged command) |
Longer, contextual clarification — e.g. asking whether the user meant an overview of agent/subagent types, or a list of installed plugins |
Nothing indicates the cost or the reply shape changed between 2.1.273 and 2.1.274. There is no
release-note entry we could find for this path, and no way for a caller to tell in advance which
of the seven observed costs a given call will land near.
What Should Happen?
Any of these would help, in order of preference:
- Give non-interactive callers a way back to the old free, deterministic rejection. A script,
CI job, or agent that sends a mistyped or unsupported slash command via claude -p now pays a
real, unpredictable amount for what used to be instant and free, with no opt-out.
- Bound the fallback reply's length, so its cost stays in a narrow, predictable band instead
of ranging from under a cent to well over ten cents for the same input.
- Document the change. The move from a local rejection to a model-routed fallback, and its
cost, do not appear to be documented anywhere a caller would find them before hitting it.
Error Messages/Logs
There is no error — every call below succeeds and returns a result record. The defect is the
cost and its variance, not a failure.
Command used for every sample below:
claude -p "/plugin-types" --output-format stream-json --verbose
(any unregistered slash command reproduces the same fallback path; this one was already
instrumented by an internal test)
total_cost_usd observed across 7 back-to-back calls on 2.1.274, same session, same unflagged
install, no conversation state carried between calls:
0.00917
0.1234
0.023845
0.0212
0.02302
0.020645
0.025795
Sample 2.1.274 reply text (paraphrased length, not verbatim, to avoid quoting a live model
response at length): a multi-sentence clarification stating the command isn't installed in this
session, then asking whether the user meant an overview of agent/subagent types or a list of
installed plugins.
2.1.273 baseline (single measurement, recorded 2026-09-16): total_cost_usd 0.000951, short
fallback line.
Steps to Reproduce
-
Install an unflagged, plain Claude Code build.
-
Run:
claude -p "/some-unregistered-command" --output-format stream-json --verbose
-
Read the result record's total_cost_usd and result text from the NDJSON output.
-
Repeat step 2 several times in the same session. The cost varies noticeably call to call for
the identical input.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.272
Claude Code Version
2.1.274
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
Is this a regression?
Not a functional regression — nothing breaks, and the older free/deterministic behavior was
deliberately replaced starting 2.1.273. But the further, undocumented rise and the run-to-run
variance observed on 2.1.274 look like an unintended side effect of whatever changed the
fallback's prompting or reply length between these two point releases, not an intentional design
change in its own right.
Where this was found
Found incidentally while re-anchoring an unrelated string extractor in an internal CLI-build
diffing tool, whose live-tier test suite already probed this exact command as a two-arm control
(one arm with a hooks-related rollout flag, one without) to prove the flag changes local command
recognition. The flagged arm's behavior (a local, free command handler) is unaffected by any of
this — only the unflagged arm's fallback for an unrecognized command is in scope here.
Related issues
| Issue |
State |
Relationship |
| #88387 |
open |
Filed 2026-08-20 against 2.1.238: -p mode's Unknown command: /foo still printed a fixed literal and exited 0 at that version — confirms the free, deterministic behavior was still in place after this project's own builds moved past it. Its ask (non-zero exit code) would no longer be sufficient on its own: once the reply is model-generated free text rather than a fixed literal, exit code alone still leaves automation with no reliable way to detect "command not found" vs. a real answer. Worth cross-linking. |
| #76066 |
closed |
A maintainer's retest comment on 2.1.233 confirms "a nonexistent command still prints Unknown command" — pins the deterministic behavior at least through 2.1.233. Together with #88387, this narrows the change window this report describes to somewhere between 2.1.238 and 2.1.273. Worth cross-linking. |
No cost ceiling is asserted in this report
Our own test suite carries an internal cost ceiling for CI purposes, but that number is a
project-local test guard we picked ourselves, not a documented Claude Code limit, so it is left
out of this report. The seven measurements above are the actual observations this report is
based on.
Preflight Checklist
What's Wrong?
An unrecognized slash command used to be rejected locally, for free, with a fixed error string.
As of 2.1.273 it instead routes through the model via a new
unknown_command_fallbackattachment kind, at a real cost. Between 2.1.273 and 2.1.274, the cost for the identical input
rose roughly 20-27x, and kept varying a lot run to run on the same build:
Unknown command: /some-commandNothing indicates the cost or the reply shape changed between 2.1.273 and 2.1.274. There is no
release-note entry we could find for this path, and no way for a caller to tell in advance which
of the seven observed costs a given call will land near.
What Should Happen?
Any of these would help, in order of preference:
CI job, or agent that sends a mistyped or unsupported slash command via
claude -pnow pays areal, unpredictable amount for what used to be instant and free, with no opt-out.
of ranging from under a cent to well over ten cents for the same input.
cost, do not appear to be documented anywhere a caller would find them before hitting it.
Error Messages/Logs
Steps to Reproduce
Install an unflagged, plain Claude Code build.
Run:
claude -p "/some-unregistered-command" --output-format stream-json --verboseRead the
resultrecord'stotal_cost_usdandresulttext from the NDJSON output.Repeat step 2 several times in the same session. The cost varies noticeably call to call for
the identical input.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.272
Claude Code Version
2.1.274
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
Is this a regression?
Not a functional regression — nothing breaks, and the older free/deterministic behavior was
deliberately replaced starting 2.1.273. But the further, undocumented rise and the run-to-run
variance observed on 2.1.274 look like an unintended side effect of whatever changed the
fallback's prompting or reply length between these two point releases, not an intentional design
change in its own right.
Where this was found
Found incidentally while re-anchoring an unrelated string extractor in an internal CLI-build
diffing tool, whose live-tier test suite already probed this exact command as a two-arm control
(one arm with a hooks-related rollout flag, one without) to prove the flag changes local command
recognition. The flagged arm's behavior (a local, free command handler) is unaffected by any of
this — only the unflagged arm's fallback for an unrecognized command is in scope here.
Related issues
-pmode'sUnknown command: /foostill printed a fixed literal and exited 0 at that version — confirms the free, deterministic behavior was still in place after this project's own builds moved past it. Its ask (non-zero exit code) would no longer be sufficient on its own: once the reply is model-generated free text rather than a fixed literal, exit code alone still leaves automation with no reliable way to detect "command not found" vs. a real answer. Worth cross-linking.Unknown command" — pins the deterministic behavior at least through 2.1.233. Together with #88387, this narrows the change window this report describes to somewhere between 2.1.238 and 2.1.273. Worth cross-linking.No cost ceiling is asserted in this report
Our own test suite carries an internal cost ceiling for CI purposes, but that number is a
project-local test guard we picked ourselves, not a documented Claude Code limit, so it is left
out of this report. The seven measurements above are the actual observations this report is
based on.