CLAUDE LABJP
RELEASE — Claude Code v2.1.246 shipped on August 26, adding a startup warning for Bash allow rules that put a wildcard ahead of the subcommandPERMISSIONS — /permissions now has an Auto mode tab, so you can see in one place what runs automatically and where Claude still stops to askMEMORY — Unbounded memory growth in long interactive sessions is fixed: subagent tool results are released once they scroll out of the recent display windowMCP — In headless and remote sessions, a tool call interrupted by an incoming message is now reported as an explicit interrupted error instead of completing with no outputRUNNER — claude self-hosted-runner gains --proxy-authorization-command and --proxy-authorization-file for egress proxies that issue a fresh auth header on every connectionLIMITS — The 50% weekly limit increase runs through August 31 for Pro, Max, Team, and seat-billed Enterprise accounts, which leaves four daysRELEASE — Claude Code v2.1.246 shipped on August 26, adding a startup warning for Bash allow rules that put a wildcard ahead of the subcommandPERMISSIONS — /permissions now has an Auto mode tab, so you can see in one place what runs automatically and where Claude still stops to askMEMORY — Unbounded memory growth in long interactive sessions is fixed: subagent tool results are released once they scroll out of the recent display windowMCP — In headless and remote sessions, a tool call interrupted by an incoming message is now reported as an explicit interrupted error instead of completing with no outputRUNNER — claude self-hosted-runner gains --proxy-authorization-command and --proxy-authorization-file for egress proxies that issue a fresh auth header on every connectionLIMITS — The 50% weekly limit increase runs through August 31 for Pro, Max, Team, and seat-billed Enterprise accounts, which leaves four days
Articles/Claude Code
Claude Code/2026-08-27Intermediate

Curating the /model picker with modelPicker, and what replacing the lineup hides

Claude Code v2.1.242 added modelPicker, which lets you write the /model lineup yourself. Here is how appending differs from replacing, why project settings are ignored, and where it quietly narrows what availableModels allows.

Claude Code235modelPickermodel configurationsettings.json7operations23

I opened /model to pick the third row, and pressed the one below it. Again.

There are two or three rows I actually use. The rest sit above them, and my fingers keep landing where the row used to be rather than where it is.

Claude Code v2.1.242 added modelPicker, a setting that lets you write that lineup yourself. I assumed it was cosmetic. Writing one turned out to involve a few decisions that are not obvious from the key name — what disappears when you replace the built-in rows, and which settings file actually gets read.

The default lineup is built for everyone, which makes it long for one person

Here is what the built-in aliases point at.

AliasWhat it selects
defaultA special value that clears any model override and reverts to your account's runtime default. Not an alias to a model
bestFable 5 where your organization has access to it, otherwise the latest Opus
fableClaude Fable 5
opusThe latest Opus
sonnetThe latest Sonnet
haikuThe fast, efficient Haiku for simple tasks
opus[1m] / sonnet[1m]The 1 million token context window variants
opusplanopus during plan mode, then sonnet for execution

What those aliases resolve to also depends on where you are connected.

Provideropussonnet
Anthropic APIOpus 5Sonnet 5
Claude Platform on AWSOpus 5Sonnet 4.6
Amazon Bedrock / Google Cloud's Agent PlatformOpus 5Sonnet 4.5
Microsoft FoundryOpus 4.6Sonnet 4.5

That coverage is a good default. But when you are an indie developer running a handful of projects on your own, the rows you reach for during the day and the ones you hand long jobs to at night settle into a small, stable set. My hesitation was never about which model to pick. It was about which position that model happened to occupy today.

The smallest useful modelPicker

modelPicker is an object with an options array and an optional replaceBuiltInOptions boolean. Each row requires model; label and description are optional.

{
  "modelPicker": {
    "options": [
      { "model": "opus", "label": "Design and investigation" },
      {
        "model": "sonnet",
        "label": "Daytime implementation",
        "description": "Enough for most of what I do"
      },
      { "model": "haiku", "label": "Formatting and lookups" }
    ]
  }
}

Each row's model is taken verbatim, so it accepts anything --model accepts: an alias like opus, an Anthropic model ID, or a provider-format ID for Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or an LLM gateway.

Leave out label and Claude Code titles the row with its built-in name for a model it recognizes, or with the model ID otherwise. Leave out description and it writes a generic second line.

One point worth stating plainly: a label changes what the picker shows, not which model runs. A row you name "production" does not become a production model — the ID in model is what gets used. It sounds obvious, but while you are arranging labels it is easy to lose track of which name is sitting on which ID. Opening /model right after you save is a cheap way to keep them aligned.

Appending versus replacing

replaceBuiltInOptions defaults to false. In that state your rows are added after the built-in lineup, and Claude Code skips any listed model the built-in lineup already covers.

Set it to true and the picker shows only your rows, plus Default, plus a row for the model the session is already using. Here is what goes away.

Where the row comes fromreplaceBuiltInOptions: falsereplaceBuiltInOptions: true
The built-in lineupShown firstHidden
Rows added for availableModels entriesShownHidden
Models found by gateway discoveryShownHidden
ANTHROPIC_CUSTOM_MODEL_OPTIONShownHidden
Default and the current modelShownShown

On my own machine I run with true. A three-row picker helped more than I expected it to. In an environment with an internal gateway or Bedrock in the mix, though, I would start at false. Turning it on hides the rows gateway discovery found, and the person who discovers that is usually not the person who wrote the setting.

The same applies to ANTHROPIC_CUSTOM_MODEL_OPTION. That single custom entry sits after the built-in rows, and any modelPicker rows you append come after it. Switch to true and both disappear together.

Project settings are ignored on purpose

This is where my instincts were wrong.

Claude Code reads modelPicker from managed settings, --settings, and user settings. It ignores the key in project and local settings, so a repository you clone cannot relabel your picker.

Beyond that, the highest-precedence of those three supplies the entire lineup. Claude Code never combines lineups from two sources. Three rows in user settings and two in managed settings does not give you five — it gives you the two from managed settings.

If you are used to committing .claude/settings.json and sharing it with a team, expect to trip here once. I put the key in project settings, opened /model, saw nothing change, and started doubting my JSON. The JSON was fine. The file was the problem.

There is a comparable "written here, applies there" gap around default models. Adding ANTHROPIC_DEFAULT_MODEL Changes Nothing While ANTHROPIC_MODEL Is Still Set covers that one.

Layering it over availableModels can narrow your choices

Writing a modelPicker does not exempt you from availableModels. The allowlist still applies to your rows, and a row outside it will not appear.

The trap is in how you add entries to that allowlist. An entry naming a specific model in a family disables that family's wildcard. Using the documented example, ["sonnet", "claude-sonnet-4-5"] allows only Sonnet 4.5 versions — not every Sonnet.

That interacts badly with a very natural workflow: you pin specific production model IDs in your picker, then add those same IDs to the allowlist so the rows survive. The wildcard you thought was keeping the whole family available quietly stops doing so.

Reversing the order avoids it:

  1. Decide in availableModels what should remain selectable
  2. Check whether you have mixed wildcards and specific IDs in the same family
  3. Then write the modelPicker lineup
  4. Open /model and count the rows against what you expected

Step 4 is the one you will want to skip. The picker does not announce what is missing, so counting is the fastest check I found.

Reading a row that never shows up

When a row you wrote does not appear, Claude Code has checked it against the session and taken one of three paths.

OutcomeWhat it means
DroppedA row Claude Code cannot serve — a retired model, or one your organization has no access to
Grayed outA row you cannot select yet, shown with the reason, and moved to the bottom of the list
No row survivesClaude Code keeps the built-in lineup, filtered by the allowlist as usual

A row it cannot parse is dropped on its own, and the rest are kept. Your settings file does not fail wholesale, so when exactly one row is missing, suspect that row's syntax first.

Grayed-out rows are not removed; they move to the bottom. If the order looks wrong, scroll down before you edit anything — the reason is printed right there.

Where to start

Write a single row and open /model. Leave replaceBuiltInOptions alone and add something like { "model": "sonnet", "label": "Daytime implementation" }. Your label appears at the end of the built-in lineup, and from there you can decide whether replacing the rest is worth it.

Once the lineup settles, the next thing that starts to matter is what you keep re-sending to those models. I wrote up how I decide the cache lifetime after stepping away in I decide the prompt cache TTL by where I come back to, not how long I was away.

It is a small setting. Having the screen you open every day match the way you actually work turned out to be a better trade than I expected.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-08-25
A One-Letter Typo in settings.json Is Ignored Without a Single Warning
I diffed claude doctor output between a settings.json with misspelled keys and a correct one. There was no difference at all. Here is what actually gets validated, what slips through, and a small check that catches typos before they cost you a day.
Claude Code2026-08-25
One Space in a Folder Name Turned 80 Checks Into Zero
An inspection loop reported 80 files checked and 0 readable. The files were fine. Here is how word splitting turns path fragments into real directories, measured side by side, plus the count assertion I now put in front of every delete-heavy batch.
Claude Code2026-08-24
The same skill lived in two places, and only one copy still had its files
Two scopes held skills with identical names. The SKILL.md files matched down to the sha256, yet one copy was missing the files its own body points to. Here is how I scanned 66 skills and rewrote the detector three times to get from four hits to two real ones.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →