claude-code - 💡(How to fix) Fix [BUG] `--settings` flag resolves sandbox filesystem paths relative to file, not project root [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46111Fetched 2026-04-11 06:28:44
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
labeled ×3

Error Message

Error Messages/Logs

Code Example



---

{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "failIfUnavailable": true,
    "autoAllowBashIfSandboxed": true,
    "filesystem": {
      "denyWrite": ["./foo"]
    }
  }
}

---

{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "failIfUnavailable": true,
    "autoAllowBashIfSandboxed": true,
    "filesystem": {
      "denyWrite": ["./bar", "../baz"]
    }
  }
}

---

mkdir ./{foo,bar,baz}

---

claude --settings .claude/sandbox.json -p 'Run `touch bar/file`'

---

claude --settings .claude/sandbox.json -p 'Run `touch foo/file`'

---

claude --settings .claude/sandbox.json -p 'Run `touch baz/file`'
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

sandbox.filesystem.denyWrite paths loaded via the --settings CLI flag resolve relative to the settings file's directory, not the project root. E.g. when using claude --settings ./claude/sandbox.json, filesystem.denyWrite: ["./spec"] does not block writes to <project_root>/spec, but filesystem.denyWrite: ["../spec"]does. This is inconsistent with how the same paths resolve in.claude/settings.json` (project scope) and contradicts the documented behavior.

The sandboxing docs define path resolution by scope:

./ or no prefix: Relative to the project root for project settings, or to ~/.claude for user settings.

There is no documented third behavior for --settings files. The --settings loader appears to use naive file-relative resolution (e.g., path.resolve(dirname(settingsFile), relativePath)) rather than the documented scope-based resolution used by the standard settings hierarchy.

The documentation for --settings states only "Path to a settings JSON file or a JSON string to load additional settings from", and it is a reasonable conclusion and design that settings from these files are merged with standard settings without resolution differences based on the settings file path.

What Should Happen?

Additional settings added via --settings flag to claude CLI should follow the same path resolution rules as the standard settings file.

Error Messages/Logs

Steps to Reproduce

  1. Create .claude/settings.json:
{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "failIfUnavailable": true,
    "autoAllowBashIfSandboxed": true,
    "filesystem": {
      "denyWrite": ["./foo"]
    }
  }
}
  1. Create .claude/sandbox.json
{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "failIfUnavailable": true,
    "autoAllowBashIfSandboxed": true,
    "filesystem": {
      "denyWrite": ["./bar", "../baz"]
    }
  }
}
  1. Run:
mkdir ./{foo,bar,baz}
  1. Run:
claude --settings .claude/sandbox.json -p 'Run `touch bar/file`'

Observe: write succeeds, despite ./bar being in the denyWrite list.

  1. Run:
claude --settings .claude/sandbox.json -p 'Run `touch foo/file`'

Observe: write is blocked, as expected.

  1. Run:
claude --settings .claude/sandbox.json -p 'Run `touch baz/file`'

Observe: write is blocked. ../baz resolves from .claude/ up to <project-root>/baz (file-relative resolution in the --settings code path, undocumented and unexpected). The same ./ prefix in./foo from .claude/settings.json resolves to <project-root>/foo (project-root-relative, per docs).

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.1.100

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

No response

extent analysis

TL;DR

The issue can be fixed by updating the --settings loader to use the same path resolution rules as the standard settings file, which resolve relative paths to the project root.

Guidance

  • The problem arises from the --settings loader using naive file-relative resolution instead of the documented scope-based resolution.
  • To verify the issue, follow the steps to reproduce and observe the inconsistent behavior of path resolution.
  • A potential workaround is to use absolute paths or paths relative to the project root in the denyWrite list, but this may not be desirable or practical.
  • The root cause is likely due to the difference in path resolution between the --settings loader and the standard settings file loader.

Example

No code snippet is provided as the issue is related to the internal implementation of the --settings loader.

Notes

The issue may be specific to the --settings loader and may not affect other parts of the Claude Code application. The fix may require changes to the internal implementation of the loader.

Recommendation

Apply a workaround by using absolute paths or paths relative to the project root in the denyWrite list, as updating the --settings loader may require significant changes to the application.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING