Skip to content

fix: remove single-quoted Python literal from claude stream processor#153

Open
alilxxey wants to merge 1 commit intoasklokesh:mainfrom
alilxxey:fix/grep-stream-processor-quoting
Open

fix: remove single-quoted Python literal from claude stream processor#153
alilxxey wants to merge 1 commit intoasklokesh:mainfrom
alilxxey:fix/grep-stream-processor-quoting

Conversation

@alilxxey
Copy link
Copy Markdown

@alilxxey alilxxey commented Apr 8, 2026

The claude provider pipes stream-json output through python3 -u -c '...' to track tool usage and update the dashboard orchestrator. The Grep branch used f"pattern: {tool_input.get('pattern', '')}", embedding four single quotes inside what is already a bash single-quoted string.

Bash toggles its SQ state on every literal ', so the four quotes fall back to SQ-in state (even number of toggles), hiding the problem from bash syntax checks. But each pair also strips its contents out of the SQ, so 'pattern' becomes a bare word and Python receives tool_input.get(pattern, ) -- a valid-but-wrong expression that raises NameError: name "pattern" is not defined on every Grep call.

The exception aborts the inner for item in content loop before update_orchestrator_task runs, so Grep invocations were silently missing from .loki/state/agents.json and the dashboard tool counter. Claude sessions continued, but every Grep also printed a spurious [Parse error: name 'pattern' is not defined] to stderr.

Fix: use double quotes and string concatenation, which stays safe inside bash SQ. Add BUG-RUN-004 regression assertions in tests/test-bugfix-audit.sh to prevent reintroducing the pattern.

Description

The claude provider pipes stream-json output through python3 -u -c '...'
to track tool usage in the dashboard orchestrator. The Grep branch at
autonomy/run.sh:9743 used:

  tool_desc = f"pattern: {tool_input.get('pattern', '')}"                                                           

embedding four single quotes inside what is already a bash single-quoted
heredoc. Bash cannot contain a literal ' inside '...' — every '
toggles SQ state. Four toggles leave the shell back in SQ mode (which is
why bash -n sees no syntax error), but each pair strips its contents
out of the SQ. Python receives:

  tool_desc = f"pattern: {tool_input.get(pattern, )}"                                                               

a valid-but-wrong expression — pattern is now a bare identifier
instead of a string literal — and crashes with:

  NameError: name 'pattern' is not defined                                                                        

The exception is caught at run.sh:9818 and printed to stderr as
[Parse error: name 'pattern' is not defined], which users see
repeatedly in logs — once per Grep tool call. Because the exception
exits the inner for item in content loop before
update_orchestrator_task(tool, tool_desc) runs, Grep calls are also
silently missing from .loki/state/agents.json and the dashboard
tool counter undercounts.

Reproduction

Isolated repro confirming the exact NameError:

python3 -u -c '                                                                                                       
def f(tool_input):                                                                                                    
    tool_desc = f"pattern: {tool_input.get('pattern', '')}"
    return tool_desc                                                                                                  
print(f({"pattern": "hello"}))                                                                                      
'                                                                                                                     
# NameError: name 'pattern' is not defined                                                                          
# (python traceback shows: tool_input.get(pattern, ) -- quotes stripped)                                              
                                                                                                                      
Root cause                                                                                                            
                                                                                                                      
Introduced in commit f7ea661 ("Fix dashboard to always show orchestrator                                              
agent"). In the same commit the Glob branch one line below correctly uses
double quotes (tool_input.get("pattern", "")) — only the Grep branch was                                              
written with single quotes.                                                                                           
                                                                                                                      
Unrelated to the historical CHANGELOG.md:5738 entry about                                                             
name 'pattern' is not defined — that earlier bug was in a different                                                 
Python heredoc and was fixed by switching to LOKI_CONTEXT env var.                                                    
                                                                                                                      
Fix                                                                                                                   
                                                                                                                      
Use double quotes and string concatenation, which is SQ-safe in the bash                                              
heredoc:
                                                                                                                      
tool_desc = "pattern: " + tool_input.get("pattern", "")                                                               
Added an inline comment warning future editors not to introduce single
quotes inside the python3 -u -c '...' block. The comment itself is                                                    
carefully written without any single-quote characters.                                                              
                             

## Type of Change

- [X] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that changes existing behavior)
- [ ] Documentation update
- [ ] Refactor (no functional changes)
- [ ] Test improvement

## Checklist

- [X] Shell scripts pass syntax validation (`bash -n autonomy/run.sh && bash -n autonomy/loki`)
- [X] All existing tests pass
- [X] New tests added for new functionality (where applicable)
- [X] No emojis in code, comments, documentation, or commit messages
- [X] Version bumped in all required files (if this is a release -- see CLAUDE.md Release Workflow)
- [X] Code follows existing patterns and style conventions

## CLA Acknowledgment

- [X] I have read and agree to the [Contributor License Agreement](CLA.md)

The claude provider pipes stream-json output through `python3 -u -c '...'`
to track tool usage and update the dashboard orchestrator. The Grep branch
used `f"pattern: {tool_input.get('pattern', '')}"`, embedding four single
quotes inside what is already a bash single-quoted string.

Bash toggles its SQ state on every literal `'`, so the four quotes fall
back to SQ-in state (even number of toggles), hiding the problem from
bash syntax checks. But each pair also strips its contents out of the
SQ, so `'pattern'` becomes a bare word and Python receives
`tool_input.get(pattern, )` -- a valid-but-wrong expression that raises
`NameError: name "pattern" is not defined` on every Grep call.

The exception aborts the inner `for item in content` loop before
`update_orchestrator_task` runs, so Grep invocations were silently
missing from `.loki/state/agents.json` and the dashboard tool counter.
Claude sessions continued, but every Grep also printed a spurious
`[Parse error: name 'pattern' is not defined]` to stderr.

Fix: use double quotes and string concatenation, which stays safe
inside bash SQ. Add BUG-RUN-004 regression assertions in
tests/test-bugfix-audit.sh to prevent reintroducing the pattern.
@alilxxey alilxxey requested a review from asklokesh as a code owner April 8, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant