Skip to content

fix: prevent undeletable nul file on Windows#13406

Closed
ASidorenkoCode wants to merge 1 commit into
anomalyco:devfrom
ASidorenkoCode:fix/windows-nul-file
Closed

fix: prevent undeletable nul file on Windows#13406
ASidorenkoCode wants to merge 1 commit into
anomalyco:devfrom
ASidorenkoCode:fix/windows-nul-file

Conversation

@ASidorenkoCode
Copy link
Copy Markdown
Contributor

@ASidorenkoCode ASidorenkoCode commented Feb 13, 2026

Problem

On Windows, OpenCode uses Git Bash as the shell for executing commands. When the AI model generates commands with Windows-style > nul or 2>nul redirection, Git Bash interprets this literally (creating a file named nul) instead of routing to the null device. Since nul is a reserved Windows device name, the file cannot be deleted through normal Windows file operations.

Before (v1.1.63) — nul file created, shows in Modified Files

before (1 1 63)

The undeletable nul file in Windows Explorer

nul

After (this fix) — no nul file created

after

Root cause

spawn('echo test 2>nul', { shell: 'C:/Program Files/Git/bin/bash.exe' }) creates a literal nul file because Git Bash doesn't recognize nul as a Windows null device — it treats it as a regular filename.

Fix

Two-pronged approach:

  1. Command sanitization (Shell.sanitizeNullRedirect()): Before spawning any command, rewrites null-device redirections to match the actual shell:

    • Git Bash: >nul / 2>nul>/dev/null / 2>/dev/null
    • cmd.exe/PowerShell: >/dev/null>NUL (reverse direction)

    Applied in both bash.ts (tool execution) and prompt.ts (shell execution path).

  2. Model guidance: Added a note to the bash tool description instructing models to use /dev/null instead of nul on Windows.

Changes

  • packages/opencode/src/shell/shell.ts: Added isUnixLike() and sanitizeNullRedirect() utilities to the Shell namespace
  • packages/opencode/src/tool/bash.ts: Call Shell.sanitizeNullRedirect() before spawning
  • packages/opencode/src/tool/bash.txt: Added Windows /dev/null guidance for models
  • packages/opencode/src/session/prompt.ts: Call Shell.sanitizeNullRedirect() before spawning in shell execution path

Tested

On Windows 11 with Git Bash. Before: echo test 2>nul creates an undeletable nul file. After: no nul file is created, output is correctly suppressed.

Fixes #13369
Fixes #11586
Fixes #11403
Fixes #8108

On Windows, OpenCode uses Git Bash as the shell. When the AI model generates
Windows-style `> nul` or `2>nul` redirection, Git Bash interprets this literally
and creates a file named `nul` instead of routing to the null device. Since `nul`
is a reserved Windows device name, the file cannot be deleted through normal
Windows file operations.

This adds a `sanitizeNullRedirect()` helper that rewrites null-device redirections
to match the actual shell: `>nul` becomes `>/dev/null` for Git Bash, and vice versa
for cmd.exe/PowerShell. Applied in both the bash tool and the shell execution path.
Also adds guidance to the bash tool description so models prefer `/dev/null`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@adrunkhuman
Copy link
Copy Markdown

The regex (\d?>)\s*(?:nul|NUL)\b will convert >nul even inside quoted strings, comments, and heredocs:

echo "Use >nul here"           # becomes "Use >/dev/null here"
# Tip: use >nul on Windows     # becomes # Tip: use >/dev/null on Windows

The \b word boundary also matches at /, so >nul/backup.txt becomes >/dev/null/backup.txt.

@breggles
Copy link
Copy Markdown

How to delete the undeletable file: https://dev.to/tishonator/how-to-delete-the-un-deletable-nul-file-created-by-claude-console-on-windows-11-33a9

(Still needs fixing, of course.)

@github-actions
Copy link
Copy Markdown
Contributor

Closing this pull request because it has had no updates for more than 60 days. If you plan to continue working on it, feel free to reopen or open a new PR.

@github-actions github-actions Bot closed this Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants