[Windows] Task agent output read fails - type builtin + MSYS path mangling + deny list not in system prompt

Resolved 💬 2 comments Opened Feb 13, 2026 by yangzealliator-yz Closed Mar 14, 2026

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

  1. Launch a Task agent (subagent) in Claude Code
  2. Agent completes and writes output to %TEMP%\claude\...\tasks\<id>.output
  3. 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:

  1. type is a Git Bash builtin — In Git Bash, type shows command types (like type ls → "ls is aliased to..."), it does NOT read file contents like Windows CMD's type. CC should use cat or the Read tool instead.
  2. MSYS path mangling — Git Bash strips backslashes from C:\Users\..., turning it into C: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:

  1. New session: LLM doesn't know cat is denied → tries it → gets blocked → wastes 1 round-trip
  2. After context compression: LLM forgets previous denial errors → tries again → wastes another round-trip
  3. 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 |

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗