Skip to content

Settings Parser Fails on Complex Commands with Embedded Parentheses #14522

Closed as not planned

Description

@pentafive

Summary

The settings file permission parser fails when processing Bash commands with embedded parentheses (e.g., PowerShell commands with COM object method calls), displaying a validation error: "Empty parentheses. Either specify a pattern or use just 'Bash' without parentheses." This prevents Claude Code from starting and requires manual editing of the settings file.


Environment

  • Claude Code Version: 2.0.72
  • Platform: Linux (WSL2)
  • OS Version: Linux 6.6.87.2-microsoft-standard-WSL2
  • Shell: bash
  • Settings File: <project>/.claude/settings.local.json

Detailed Description

Trigger Event

User had previously approved PowerShell commands that included complex COM object method calls. These commands were stored in .claude/settings.local.json as permission patterns. When Claude Code attempted to load the settings file on startup, the parser encountered embedded parentheses in the function calls and failed validation.

Error Message

Settings Error

 /home/cyber/projects/.claude/settings.local.json
  └ permissions
    └ allow
      └ "Bash(powershell.exe -Command '
  $shell = New-Object -ComObject Shell.Application
  $fenix = $shell.NameSpace(17).Items() | Where-Object { $_.Name -like ""*fenix*"" }
  ...
      └ Empty parentheses. Either specify a pattern or use just "Bash" without parentheses.

Problematic Permission Entries

Lines 80-81 in settings file (before fix):

"Bash(powershell.exe -Command '\n$shell = New-Object -ComObject Shell.Application\n$fenix = $shell.NameSpace(17).Items() | Where-Object { $_.Name -like \"\"*fenix*\"\" }\n...')",
"Bash(powershell.exe -Command '\n$shell = New-Object -ComObject Shell.Application\n...\n$dest.CopyHere($file, 16)\n...')"

The parser encountered:

  • $shell.NameSpace(17).Items() - Method calls with parentheses
  • Where-Object { $_.Name -like ... } - Lambda blocks with parentheses
  • $dest.CopyHere($file, 16) - Method calls with arguments

Parser Behavior

The permission parser uses a pattern Bash(pattern) where pattern is expected to be a wildcard or command prefix. It fails when:

  1. The pattern contains () (empty parentheses) - interpreted as invalid syntax
  2. The pattern contains method calls like .Items() or .CopyHere(arg, arg) - parser sees the embedded () and rejects

Impact Assessment

User Impact: Critical

  • Prevents Claude Code from starting - User must select "Exit and fix manually"
  • No graceful degradation - Cannot skip just the invalid entries
  • Entire settings file skipped - "Files with errors are skipped entirely, not just the invalid settings"
  • Requires manual JSON editing to recover

Frequency: Low

  • Only affects users who:
    • Run complex PowerShell commands with method calls
    • Use "Don't ask again" to persist those commands
    • Are on WSL/Linux systems executing Windows PowerShell

Data Loss Risk: None

  • Settings file remains intact, just rejected by parser
  • User can manually edit to recover

Reproduction Steps

Minimal Reproduction

  1. Create or edit <project>/.claude/settings.local.json with this content:
{
  "permissions": {
    "allow": [
      "Bash(powershell.exe -Command '$shell.Method()')"
    ]
  },
  "outputStyle": "default"
}
  1. Start Claude Code

Expected Result:

  • Claude Code starts normally
  • Permission pattern is loaded

Actual Result:

  • Settings validation error: "Empty parentheses. Either specify a pattern or use just 'Bash' without parentheses"
  • User forced to choose "Exit and fix manually" or "Continue without these settings"

Real-World Reproduction

  1. Approve a Bash command containing a PowerShell script with COM object method calls:

    $shell = New-Object -ComObject Shell.Application
    $items = $shell.NameSpace(17).Items()
  2. Select "Don't ask again" when prompted for permission

  3. Exit Claude Code

  4. Restart Claude Code

Expected Result:

  • Claude Code starts normally
  • Permission is preserved and applied

Actual Result:

  • Claude Code displays settings validation error
  • User forced to choose "Exit and fix manually" or "Continue without these settings"
  • All permissions in the file are skipped

Root Cause Analysis

The permission pattern parser appears to use a simple regex or string matching approach that:

  1. Expects Bash(pattern) format
  2. Interprets any () within the pattern as potentially invalid
  3. Does not account for:
    • Escaped characters in bash commands
    • Multiline commands with \n
    • Programming language syntax (PowerShell, Python) within bash strings
    • Method calls, function invocations, or lambda expressions

Why This Fails

The PowerShell command is wrapped as:

Bash(powershell.exe -Command 'SCRIPT WITH PARENTHESES')

The parser sees .NameSpace(17) and .Items() and interprets the embedded () as malformed permission syntax rather than part of the command string.


Workarounds

Immediate Fix (Manual Edit)

Replace the specific long PowerShell commands with a wildcard pattern:

"Bash(powershell.exe:*)"

This allows all PowerShell commands but loses granularity.

Preventive Workaround

When using complex commands:

  • Avoid "Don't ask again" for commands with method calls or complex syntax
  • Use wildcard patterns instead: Bash(powershell.exe:*), Bash(python3:*)

Suggested Fixes

Option 1: Improve Parser Escaping (Recommended)

Treat the content inside Bash(...) as a literal string, not a pattern with special syntax:

  • Only parse the outer Bash( and ) delimiters
  • Everything between is the command pattern (can contain any characters)
  • Escape handling should preserve parentheses in strings

Option 2: Validation Before Saving

Before writing permissions to settings file:

  • Validate that the command can be re-parsed successfully
  • If validation fails, fall back to wildcard pattern
  • Warn user that specific command was simplified

Option 3: Alternative Format for Complex Commands

For commands with special characters, use an alternate encoding:

{
  "pattern": "Bash",
  "command": "powershell.exe -Command '...'"
}

This separates the pattern from the full command and avoids parser ambiguity.


Related Issues

Potentially Related:


Debug Log Evidence

Session: ca033e2f-1c45-46dc-9ca5-299378395dff
Debug Log: ~/.claude/debug/ca033e2f-1c45-46dc-9ca5-299378395dff.txt

Settings load failure (Line ~6):

2025-12-18T02:13:09.837Z [DEBUG] Applying permission update: Adding 15 allow rule(s) to destination 'userSettings': ...
2025-12-18T02:13:09.837Z [DEBUG] Applying permission update: Adding 91 allow rule(s) to destination 'localSettings': ...

Notice that localSettings has 91 rules loaded successfully after manual fix, indicating the file structure is otherwise valid.


Files for Reference

  1. Settings File (Before Fix): Contains problematic PowerShell commands on lines 80-81
  2. Settings File (After Fix): Replaced with "Bash(powershell.exe:*)"
  3. Debug Log: ~/.claude/debug/ca033e2f-1c45-46dc-9ca5-299378395dff.txt (58 KB)

Test Cases for Validation

The parser should successfully handle these permission patterns:

[
  "Bash(ls:*)",
  "Bash(python3:*)",
  "Bash(node -e 'console.log()')",
  "Bash(bash -c 'echo $(date)')",
  "Bash(powershell.exe -Command '$shell.Method()')",
  "Bash(python3 -c 'import sys; print(sys.version)')"
]

Currently FAILS on:

  • Bash(powershell.exe -Command '$shell.Method()') - Method calls with ()
  • Any command containing .NameSpace(), .Items(), .GetFolder(), etc.

Next Steps

  • File GitHub issue with reproduction steps
  • Attach example settings file excerpt (sanitized)
  • Propose parser fix (Option 1 recommended)
  • Add test cases for complex command patterns

Activity

  1. github-actions commented on Dec 18, 2025

    @github-actions

    Found 1 possible duplicate issue:

    1. [Bug] Configuration Parsing Error #6865

    This issue will be automatically closed as a duplicate in 3 days.

    • If your issue is a duplicate, please close it and 👍 the existing issue instead
    • To prevent auto-closure, add a comment or 👎 this comment

    🤖 Generated with Claude Code

  2. pentafive commented on Dec 18, 2025

    @pentafive
    Author

    Thanks for flagging the potential duplicate. While #6865 describes the same underlying parser bug, I'd argue this issue provides significantly more value:

    Why Keep This Issue Open

    Better Reproduction:

    Root Cause Analysis:

    Actionable Fixes:

    • 3 proposed solutions with implementation details
    • Test cases for validation
    • Clear recommendation (Option 1: treat content as literal string)
    • [Bug] Configuration Parsing Error #6865 has no proposed fixes

    Better Context:

    Suggestion

    Either:

    1. Keep Settings Parser Fails on Complex Commands with Embedded Parentheses #14522 as the primary issue (more complete)
    2. Merge the relevant details from [Bug] Configuration Parsing Error #6865 into this issue
    3. Close [Bug] Configuration Parsing Error #6865 as duplicate of Settings Parser Fails on Complex Commands with Embedded Parentheses #14522 (not the other way around)

    The extra detail here should make it much easier for the team to implement a fix. Happy to consolidate if needed.

  3. paul-hammant commented on Jan 17, 2026

    @paul-hammant

    It should at least say what the offending line is. One solution is to delete the offending permission

  4. github-actions commented on Feb 27, 2026

    @github-actions

    Closing for now — inactive for too long. Please open a new issue if this is still relevant.

  5. github-actions commented on Mar 8, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  6. locked as resolved and limited conversation to collaborators on Mar 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:corebugSomething isn't workinghas reproHas detailed reproduction stepsplatform:linuxIssue specifically occurs on LinuxstaleIssue is inactive

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions