Path-pattern scanner false-positives on macOS usernames containing `.`, and "always allow" option fails to persist a rule (Bash and Write only; Edit unaffected)
Summary
Three related issues in the path-pattern security scanner that produces "suspicious Windows path pattern that requires manual approval":
- False positive on macOS usernames containing a period. Any path under
/Users/<username-with-period>./...matches because the literal<letter>./looks like a Windows drive-letter pattern (C:\). macOS allows periods in usernames; on my machine the username isjosejimenezjr.(a common abbreviation for "Jr.") so every home-directory path under/Users/josejimenezjr./...triggers the scanner. - "Yes, and always allow" doesn't persist. Selecting option 2 ("always allow access to
<folder>/from this project") does not write a rule to.claude/settings.local.json. Verified by file mtime and rule count remaining unchanged after multiple selections. - Pre-installed allow-rules are bypassed. Manually adding
Write(//path/**),Write(/path/**), andBash(<exact-prefix>:*)rules to.claude/settings.local.jsondoes not suppress the scanner. The scanner runs at a layer above the permission/allow-list system. - Tool coverage: scanner fires on Bash and Write tool calls but not on Edit. Edit-tool calls to the same paths use the standard out-of-cwd permission prompt (different wording: "allow all edits in
<folder>/during this session") and are correctly suppressed by auto mode for in-project files.
Environment
- Claude Code: 2.1.123 (latest published on npm at time of report)
- macOS, username
josejimenezjr.(legal trailing period in macOS username) - Auto mode (
bypassPermissions) active
Reproduction
- macOS account with a period in the username (e.g.
josejimenezjr.). - In Claude Code with auto mode on, run a Bash command that writes to a home-directory path:
````
echo test > /Users/josejimenezjr./test.txt
- Observe prompt:
> Claude requested permissions to write to /Users/josejimenezjr./test.txt, which contains a suspicious Windows path pattern that requires manual approval.
- Pick option 2 ("Yes, and always allow access to
josejimenezjr./from this project"). - Run the same command again. Expected: silent. Actual: prompts again.
- Inspect
<project>/.claude/settings.local.json: file mtime unchanged, no new rule added. - Pre-install the following rules manually in
.claude/settings.local.json:
``json`
"Write(//Users/josejimenezjr./**)",
"Write(/Users/josejimenezjr./**)",
"Bash(echo SCANNER_PROBE:*)"
echo SCANNER_PROBE_BASH > /Users/josejimenezjr./scanner_probe.txt`. Actual: still prompts.
Run a matching
- Use the Edit tool against an existing in-project file under home dir (e.g.
<project>/.claude/settings.local.json). Actual: silent (auto mode handles it correctly). Edit on an existing file outside the project working directory under home dir prompts with the standard "Yes, allow all edits during this session" prompt, not the scanner warning.
Workaround
None known. Option 2 fails silently. Manual allow-rules are not respected by this scanner. Affected users on macOS with periods in their username must manually approve every Bash and Write call to home-directory paths.
Related
- #41763 (
bypassPermissionssilently downgrades toacceptEditsafter approving suspicious-path prompt) - same scanner family.
7 Comments
Worth calling out plainly: auto mode (
bypassPermissions) does not suppress this scanner either. The Environment block in the issue shows the repro is under auto mode, but the scanner fires regardless of permission mode (auto, default, plan). This is consistent with the architectural finding in summary point #3 - the scanner appears to run above the permission resolution layer entirely, so neither auto mode nor manual allow-rules can override it.Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Update: corrections, expanded scope, and duplicate triage
After running additional tests on a second macOS account (no period in the username) across both 2.1.116 and 2.1.123, the original report needs significant corrections. The bug surface is wider than originally reported, two findings were wrong, and there's confirmed version drift between releases.
Duplicate-candidate triage (responding to bot)
\\wsl.localhost\...), different tool surface. Surface theme of "permissions ignored" but unrelated underlying bug.<<'EOF'heredoc): architectural sibling, not a duplicate. Tested the verbatim repro on 2.1.116 - did not fire, appears silently fixed. Same shape as this bug (a content scanner producing false positives that runs above the permission resolution layer), different specific scanner. Worth referencing because if backticks were patched the same way, it suggests the path scanner can be patched similarly.Corrections to the original report
.". The trigger is any path segment ending in.anywhere under/Users/or/private/, regardless of username. Common real-world directories that fire:Mr.,Jr.,Sr.,Dr.,Co.,Inc.,Vol.1,Apr., version suffixes, abbreviated folder names. The username case is just one easy repro becausejosejimenezjr.(period for "Jr.") creates a period-ending segment in every home-directory path.Writetool to/Users/Shared/sibling_verify/Mr./writetest.txt: fires the standard out-of-cwd permission prompt ("Do you want to create writetest.txt? [...] Yes, allow all edits inMr./during this session"), not the scanner warning.Edittool: same standard prompt, no scanner.Readtool: silent, no scanner.Bashtool: scanner fires.The original report's "Bash and Write" claim was extrapolated from a parallel-tool-call test that was inconclusive (the user rejected before the Write probe completed). On clean re-test, Write does not trigger this scanner.
Version drift (2.1.116 → 2.1.123)
The regex was broadened between these versions. Concrete comparison:
| Test | 2.1.116 | 2.1.123 |
|---|---|---|
|
mkdir "/Users/foo/scanner-test/r."(period at end of arg) | fires | fires ||
mkdir "/Users/foo/scanner-test/r./newsub"(period followed by/<chars>") | silent | fires ||
mkdir "/Users/foo/scanner-test/.dotdir"(period at segment start) | silent | silent ||
ls "/Users/foo/scanner-test/r./"(period followed by/") | silent | silent |The "always allow" persistence failure is unchanged across both versions.
The 2.1.123 broadening means every command operating on a path containing any period-ending segment under
/Users/or/private/now fires the scanner, as long as there's at least one more path component after that segment. This is the user-facing regression that made the bug noticeable now.Refined regex hypothesis
For 2.1.123:
That is: under a literal
/Users/or/private/prefix, match<word-chars>.followed by either:Case-insensitive. Maintainers should confirm against actual source.
New finding: trivial bypass via runtime path construction
The scanner string-matches the visible Bash command, not the resolved path. Verified silent on 2.1.123:
Created
/Users/Shared/sibling_verify/dyn/r./with no prompt. The actual filesystem operation is identical to a literalmkdir "/Users/Shared/.../r."(which fires), but because ther.is constructed at runtime fromprintf, the scanner doesn't see it.This means the scanner is functionally a UX hint, not a security boundary - any motivated user (or AI tool call) can route around it with one line of shell. Worth knowing for fix prioritization.
Bug #2 ("Always allow doesn't persist") - additional finding
The original report covers the disk-persistence failure. Additional behavior verified: session-memory scope is also broken. After clicking option 2 ("Yes, and always allow access to scanner-test/ from this project") on a
mkdir scanner-test/q.prompt, subsequentmkdir scanner-test/rs.andmkdir scanner-test/UPPER.commands inside the same folder still prompted with the scanner. Option 2 is effectively a relabeled "option 1 (Yes)" - it neither persists to disk nor caches in session memory.Bug #3 ("Pre-installed allow-rules ignored") - confirmed on real account
Manually adding the following rules to
<project>/.claude/settings.local.json:then running
echo SCANNER_PROBE_BASH > /Users/josejimenezjr./scanner_probe.txt- scanner still fires. Confirms scanner runs above the allow-list resolution layer entirely.Hitting this on macOS — same root cause but with a folder-name pattern rather than username. My organisational top-level folder is
~/Desktop/2026/MR./(a two-letter initialism with a trailing dot, used across many projects under it), so every Edit/Write tool call against any file under that tree triggers the "suspicious Windows path pattern" prompt. Confirming the OP's findings: auto/bypass mode does not suppress it, and pre-installed allow-rules in.claude/settings.local.jsonare ignored — the scanner runs above the permission layer.This looks like a platform-detection oversight rather than an intentional cross-platform check. The patterns the scanner is matching (trailing-dot path segments, drive-letter-style fragments) are only meaningful constraints on Windows — on macOS they're fully legal path components with no special filesystem handling. The fix looks like a one-liner: gate the scanner on
process.platform === 'win32'so it only runs on hosts where these patterns are actually constrained. Failing that, apermissions.disablePathHeuristicssetting insettings.jsonwould let users opt out per-project on platforms where this is a known false-positive.Renaming the folder isn't a workable mitigation here — it's a top-level org folder with years of project files under it, including Adobe apps that store linked-asset references. The expectation is that legitimate macOS path conventions don't get blocked by a Windows-targeted heuristic.
Bumping this off
stale. Still reproduces on 2.1.143 (latest as of today), which is 27 releases past the version this was first reported on. None of the changelog entries between 2.1.124 and 2.1.143 reference the scanner, path heuristics, or the permission-layer code this lives in.Status snapshot:
~/Desktop/2026/MR./), so the bug is not specific to usernames containing.DISABLE_UPDATES=1since the original report to keep the CLI usable, which means missing every fix shipped since 2026-04-20 (memory-leak fixes in 2.1.121, MCP OAuth fixes, session-corruption recovery)Also routed through
/feedbackto the internal channel in parallel.Looking for a triage acknowledgment. The triage notes, refined regex hypothesis, version-drift table, and trivial-bypass proof are all above. The proposed fix from the thread (gate the scanner on
process.platform === 'win32', or revert to the pre-2.1.117 narrow regex) is small.Still reproduces on 2.1.173 (macOS, username
shahzaiba.) — same behavior as OP: the scanner fires beforepermissions.allowis evaluated, so no rule syntax (bare,//absolute,~/, wildcard) suppresses the prompts. Adding a data point and a working escape hatch for anyone who can't wait for a fix.Workaround that actually resolves it: rename the macOS account to drop the trailing dot
bypassPermissionsis the only in-product workaround, but it's a blunt instrument. Renaming the account (shahzaiba.→shahzaib) eliminates the false-positive entirely — and confirms the root cause is purely the<letter>./segment matching the Windows drive-letter heuristic.Rename procedure (summarized; standard macOS account rename):
mv /Users/olduser. /Users/newuser, thendscl . -change /Users/olduser. NFSHomeDirectory ...anddscl . -change /Users/olduser. RecordName olduser. newuser.ln -s /Users/newuser /Users/olduser.for any configs still holding the old path. Password, Keychain, FileVault/SecureToken all survive (tied to the account UUID, not the name).Claude Code state migration — the part that isn't obvious. Session history is keyed by path-encoded directory names, so after the rename all prior sessions disappear from
/resumeuntil you migrate:~/.claude/projects/: rename each-Users-olduser--<project>dir to the new encoding, and rewrite/Users/olduser.→/Users/newuserinside the session.jsonlfiles.~/.claude/history.jsonl,~/.claude.json(project keys — watch for a duplicate key if you've already launched once from the new path),~/.claude/settings.json, and~/.claude/plugins/*.json.~/.claude.json.Result
After the rename, with
defaultMode: "auto"restored and path-scoped rules (Edit(~/Documents/dev/**),Write(~/Documents/dev/**)): zero prompts on Write, Edit, and read-only Bash under the allowed path. The exact same rules that were dead letters before the rename work immediately once the username has no period — there's nothing wrong with the rules themselves, only the scanner layer that pre-empts them.Obviously an account rename is a drastic "fix" for a path-pattern regex, but until the scanner either anchors the drive-letter check to path starts (
^[A-Za-z]:[\\/]) or runs after the allow-list, it's the only way to get the permission system working on these machines.Bump to remove stale. Still an issue