[Windows] Background agent output file stays 0 bytes due to symlink permission failure
Summary
When launching a background agent (run_in_background=true) on Windows without Developer Mode enabled, the tasks/<agentId>.output file is created but stays permanently at 0 bytes, making it impossible to tail/read agent progress via the file path advertised in the tool result.
Environment
- OS: Windows (Developer Mode disabled)
- Claude Code version: 2.1.85 (reproduced from session analysis)
Behavior
- Background agent is dispatched with
run_in_background=true - Tool result includes:
````
output_file: C:\Users\...\tasks\a5013d4b542a4d2a9.output
If asked, you can check progress before completion by using Read or Bash tail on the output file.
- Agent runs and completes normally (JSONL log written, completion notification delivered)
- But
tasks/<agentId>.outputremains 0 bytes throughout
Root Cause
From binary analysis of claude v2.1.85, the XOH() function creates the output file as a symlink pointing to the agent's .jsonl file:
async function XOH(agentId, jsonlPath) {
try {
await Fu.symlink(jsonlPath, outputPath); // symlink to agent-<id>.jsonl
} catch {
return ry6(taskId); // fallback on failure
}
}
async function ry6(taskId) {
// Creates empty file and immediately closes it
await (await Fu.open(path, O_WRONLY|O_CREAT|O_EXCL|Qaq)).close();
return path;
}
On Windows, fs.symlink() requires SeCreateSymbolicLinkPrivilege, which is only available to administrators or users with Developer Mode enabled. Without it, the call throws EPERM, triggering the fallback ry6() which creates an empty file and closes it immediately — leaving a permanently empty output file.
The agent itself runs fine (completion notification arrives correctly), but the output file is useless.
Workaround
Enable Windows Developer Mode:Settings → Update & Security → For developers → Developer Mode: ON
This grants symlink creation permission to regular users.
Suggested Fix
In XOH(), when fs.symlink() fails on Windows, fall back to a mechanism that actually writes content — either:
fs.link()(hardlink, no special permissions needed), or- Write the output directly to the file as the agent produces it (same as the
local_bashtask type already does)
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗