[Windows] Task agent output read fails - type builtin + MSYS path mangling + deny list not in system prompt
Environment
- OS: Windows 11 (10.0.26200)
- Shell: Git Bash (MSYS2)
- Claude Code: latest stable
- Settings: Global deny rules for
Bash(cat *),Bash(head *), etc.
Bug 1: Task output read fails with type command
Steps to Reproduce
- Launch a Task agent (subagent) in Claude Code
- Agent completes and writes output to
%TEMP%\claude\...\tasks\<id>.output - CC attempts to read the output file
Expected
CC reads the task output successfully.
Actual
CC runs:
type C:\Users\chine\AppData\Local\Temp\claude\D--Projects-GameDev-Toolkit-v23\tasks\b91679d.output
Error:
/usr/bin/bash: line 1: type: C:UserschineAppDataLocalTempclaudeD--Projects-GameDev-Toolkit-v23tasksb91679d.output: not found
Root Cause
Two issues combined:
typeis a Git Bash builtin — In Git Bash,typeshows command types (liketype ls→ "ls is aliased to..."), it does NOT read file contents like Windows CMD'stype. CC should usecator theReadtool instead.- MSYS path mangling — Git Bash strips backslashes from
C:\Users\..., turning it intoC:UserschineAppData....
Bug 2: cat fallback blocked by user's own deny rules
When CC falls back to cat, it gets blocked by the user's settings.json deny rule "Bash(cat *)":
cat "C:\Users\...\tasks\b91679d.output" → permission denied
Suggested Fix
CC should use the Read tool (not Bash commands) to read Task agent output files. The Read tool bypasses both the MSYS path issue and Bash permission rules.
Bug 3 (Design Issue): Deny list not injected into LLM system prompt
Problem
The permissions.deny list in settings.json is enforced at the permission layer, but the LLM is never told which commands are denied. This means:
- New session: LLM doesn't know
catis denied → tries it → gets blocked → wastes 1 round-trip - After context compression: LLM forgets previous denial errors → tries again → wastes another round-trip
- Every compression cycle: Same pattern repeats
Current flow
LLM generates command → Permission check (deny list) → Block → Error returned → LLM learns
↓
(lost after compression)
Suggested improvement
Inject the deny list into the system prompt so the LLM never attempts denied commands:
Current: deny list → runtime block (LLM doesn't know, trial-and-error wastes tokens)
Proposed: deny list → inject into system prompt (LLM knows upfront, never attempts)
This would save ~2-4K tokens per compression cycle per denied command pattern.
Summary
| Bug | Severity | Fix |
|-----|----------|-----|
| type not cat in Git Bash | Medium | Use Read tool for task output |
| cat fallback blocked by deny | Medium | Use Read tool for task output |
| Deny list not in system prompt | Low (design) | Inject deny patterns into system prompt |
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗