Docs: Ambiguous settings merge semantics for --settings and --setting-sources flags

Resolved 💬 3 comments Opened Feb 18, 2026 by gwpl Closed Mar 19, 2026

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.json or 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:

  1. Where in the precedence chain does it land? The precedence table lists "Command line arguments" at level 2, but it's unclear if --settings is treated as level 2 or has special behavior.
  2. Does it merge with or replace other sources? "Additional" implies merge, but with which sources? All of them? Only user-level?
  3. 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:

  1. Is managed always loaded regardless? The docs don't explicitly say it's excluded from --setting-sources control.
  2. 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 user filter out project/local, and then --settings merges on top of managed+user?
  • Or does --settings act 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:

  1. Default (no flags): merge(managed, local, project, user) with left-to-right precedence
  2. --setting-sources=X,Y: merge(managed, ...only X,Y from {local,project,user})
  3. --settings=F: merge(managed, F, local, project, user) — F at precedence level 2 (if that's the intent)
  4. 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

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗