Background task output can grow unbounded via self-referential glob
Bug Description
A background Bash task whose output is written to /private/tmp/claude-{uid}/.../tasks/{task_id}.output can inadvertently read its own output file when using a glob pattern like *.output on the same directory. This creates an infinite feedback loop where the task reads its own growing output, writes more output, reads again, etc.
In my case this resulted in a single 404 GB file that silently filled the entire disk.
Steps to Reproduce
- Have a session with multiple background tasks/subagents running
- The main agent generates a Bash command to check task progress, e.g.:
``bash``
for f in /private/tmp/claude-{uid}/.../tasks/*.output; do
echo "=== $(basename $f) ==="
tail -5 "$f" 2>/dev/null || echo "not ready"
done
- This command is run as a background task, so its output is written to
.../tasks/{new_task_id}.output— the same directory it's globbing - The glob
*.outputmatches the task's own output file tail -5reads the growing file, producing more output, which grows the file, which gets read again → infinite loop
Root Cause
The background task system writes task output to the same tasks/ directory that contains all other task outputs. When a task iterates over *.output files in that directory, it includes its own output file, creating a recursive feedback loop.
The file was generated by the Claude main agent (agent=main, caller.type=direct) as a native behavior to monitor subagent progress — not by any plugin or hook.
Impact
- Silently consumed 404 GB of disk space in
/private/tmp/ - macOS reported it under "System Data" in storage settings, making it hard to diagnose
- No warnings or size limits prevented the file from growing
- The file persisted across sessions since
/private/tmp/is not cleaned on session end
Environment
- Claude Code on macOS (Darwin 25.3.0)
- APFS filesystem
- Output path:
/private/tmp/claude-{uid}/{project_hash}/{session_id}/tasks/{task_id}.output
Suggested Fixes
- Exclude self from glob: When a background task reads from the
tasks/directory, exclude its own output file - Size cap on task output files: Add a configurable maximum size (e.g. 100 MB) for
.outputfiles, truncating or stopping the task when exceeded - Write output to a separate directory: Don't write task output into the same directory where other task outputs are stored
- Periodic cleanup: Add a TTL or cleanup mechanism for old/large files in
/private/tmp/claude-{uid}/
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗