Docs: Ambiguous settings merge semantics for --settings and --setting-sources flags
AI Assistant:
Summary
The settings documentation defines a clear 5-level precedence hierarchy, but the behavior of --settings and --setting-sources CLI flags is underspecified. It is currently impossible to reason precisely about the resulting settings state when these flags are used, individually or combined.
Documentation Quotes
1. Settings Precedence (from settings.md)
Settings apply in order of precedence. From highest to lowest: 1. Managed settings (managed-settings.jsonor server-managed settings) 2. Command line arguments — Temporary overrides for a specific session 3. Local project settings (.claude/settings.local.json) 4. Shared project settings (.claude/settings.json) 5. User settings (~/.claude/settings.json)
And:
Inheritance: Settings are merged, with more specific settings adding to or overriding broader ones
2. --settings flag (from cli-reference.md)
| --settings | Path to a settings JSON file or a JSON string to load additional settings from |
3. --setting-sources flag (from cli-reference.md)
|--setting-sources| Comma-separated list of setting sources to load (user,project,local) |
Ambiguities
A. --settings merge behavior
The flag description says "additional settings", but does not specify:
- Where in the precedence chain does it land? The precedence table lists "Command line arguments" at level 2, but it's unclear if
--settingsis treated as level 2 or has special behavior. - Does it merge with or replace other sources? "Additional" implies merge, but with which sources? All of them? Only user-level?
- For nested/array settings (e.g.,
allowedTools,permissions), is the merge shallow or deep? Does it append to arrays or replace them?
B. --setting-sources scope control
The flag accepts user, project, local — but:
- Is
managedalways loaded regardless? The docs don't explicitly say it's excluded from--setting-sourcescontrol. - Does omitting a source mean it's skipped entirely, or that it falls back to defaults? E.g.,
--setting-sources user— is the resulting state only managed+user, or are project/local settings loaded but deprioritized?
C. Combining both flags
No documentation addresses what happens when both are used together:
claude --settings ./custom.json --setting-sources user
- Does
--setting-sources userfilter out project/local, and then--settingsmerges on top of managed+user? - Or does
--settingsact as a replacement for the filtered-out sources? - Or is this combination invalid/unsupported?
Desired Outcome
A precise specification that allows reasoning about settings state as a deterministic function:
resolve_settings(
managed,
user_settings,
project_settings,
local_settings,
--settings flag value,
--setting-sources flag value
) → final merged settings
Ideally documented as:
- Default (no flags):
merge(managed, local, project, user)with left-to-right precedence --setting-sources=X,Y:merge(managed, ...only X,Y from {local,project,user})--settings=F:merge(managed, F, local, project, user)— F at precedence level 2 (if that's the intent)- Both flags combined: explicit merge order
This would make the behavior reproducible, non-ambiguous, and precisely reasoned about for users configuring Claude Code across different environments (CI, team setups, personal overrides, etc.).
Environment
- Claude Code CLI
- Documentation as of 2026-02-18
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗