Description
Bug Report: After a hard crash in PowerShell, OpenCode database lock persists until OpenCode runs successfully from CMD
Environment
| Item |
Detail |
| OS |
Windows 10 Pro 22H2 (Build 19045) |
| Terminal |
Windows Terminal |
| Shell |
PowerShell 7.1 (primary), Git Bash 5.2.37 / MSYS2 (secondary) |
| OpenCode versions |
1.18.3 → upgraded to 1.18.4 → downgraded back to 1.18.3 |
| Plugins |
opencode-smart-approval v0.5.0 |
| AI Provider |
DeepSeek (deepseek-v4-pro) |
| Working directory |
Contains CJK (Chinese) characters in path |
| Install method |
npm install -g opencode-ai |
Symptoms
-
TUI crashes instantly — window flashes, alternate screen buffer activates briefly (escape sequences visible), then exits silently with exit code 0. No error message, no stack trace.
-
Mouse escape sequences flood the terminal after crash — the TUI's mouse capture mode remains active and raw ANSI sequences are written to the terminal.
-
opencode run "message" initially works, but subsequently also exits silently (exit code 0, zero output).
-
opencode session list, opencode stats, opencode debug info — all exit code 0 with zero bytes on stdout and stderr.
-
opencode --version, opencode debug paths, opencode debug startup — these continue to work. They are the only commands that don't require database access.
-
opencode serve dies immediately (no log output produced).
-
Restarting the terminal does NOT fix the problem. Only rebooting the machine temporarily resolves it.
-
The critical clue: Launching OpenCode from cmd.exe works. After a successful cmd.exe session exits normally, PowerShell also starts working again — in the same PowerShell tab that previously crashed, without restarting the shell process.
Full Debugging Journey
Step 1: Initial suspicion — mouse tracking corruption
Checked logs at %USERPROFILE%\.local\share\opencode\log\opencode.log. All level=ERROR entries were error=Aborted stack=undefined, which turned out to be user-initiated Ctrl+C interrupts, not crashes. The actual crash produced no log entry at all — characteristic of a Bun-level hard crash (SIGSEGV/SIGILL).
Found issue #24288 about Windows mouse escape sequence leakage. Verified that OPENCODE_DISABLE_MOUSE is an officially recognized env var by extracting strings from the 173MB opencode.exe binary:
useMouse:!lf.OPENCODE_DISABLE_MOUSE&&U.config.mouse
Set OPENCODE_DISABLE_MOUSE=1 as a Windows user environment variable. Mouse flooding stopped, but TUI still crashed. This ruled out mouse tracking as the primary cause.
Step 2: Database integrity check
Headless mode (opencode run "message") worked fine. This meant the core engine and AI provider were functional. The crash was specific to TUI and server mode initialization.
Ran SQLite integrity check on the database (57MB) via Python:
conn = sqlite3.connect(db_path)
cursor.execute('PRAGMA integrity_check')
# Result: ok
cursor.execute('PRAGMA wal_checkpoint(TRUNCATE)')
# Result: disk I/O error
Key finding: The main database file was intact (integrity_check: ok), but the WAL (Write-Ahead Log) was corrupted. The wal_checkpoint consistently failed with disk I/O error.
Step 3: The database lock discovery
Attempted to VACUUM the database into a repaired copy. The VACUUM succeeded on a temp copy (57.7MB → 57.5MB, integrity verified), but could not replace the original file:
PermissionError: [WinError 5] Access denied
Further investigation revealed:
del /F opencode.db → "Access is denied"
ren opencode.db opencode.db.old → "Access is denied"
- Writing a NEW file to the same directory → Works fine
- PowerShell
[IO.File]::Open with FileShare.None → Succeeds (file CAN be opened for I/O)
Conclusion: The file is not locked by another process in the traditional sense. It's a zombie file handle — the process that held it open has crashed, but Windows has not released the handle. This is a kernel-level orphaned lock that survives process termination but not reboots.
Step 4: Workaround with OPENCODE_DB env var
Used the OPENCODE_DB env var (also found in the binary strings) to point OpenCode to the repaired database at a different filename:
OPENCODE_DB=%USERPROFILE%\.local\share\opencode\opencode_fixed.db
opencode run worked again. But TUI and serve still crashed. This proved database access was necessary but not sufficient for TUI recovery.
Step 5: Binary reinstall
The upgrade log showed an EPERM error during the 1.18.3→1.18.4 upgrade:
Error: EPERM: operation not permitted, unlink '...opencode-windows-x64\bin\opencode.exe'
The old binary could not be replaced because it was in use. A subsequent downgrade may have encountered the same issue in reverse. Performed a clean reinstall:
npm uninstall -g opencode-ai
npm install -g opencode-ai@1.18.3
After reinstall, opencode run worked consistently. But TUI still crashed in PowerShell.
Step 6: The PowerShell vs CMD discovery
At this point, a hypothesis emerged: PowerShell's PTY/process model might be preventing proper cleanup of the zombie file handle.
Tested from cmd.exe:
set OPENCODE_DISABLE_MOUSE=1
set OPENCODE_DB=%USERPROFILE%\.local\share\opencode\opencode_fixed.db
opencode --pure
cmd.exe TUI launched successfully. After exiting normally:
- The old
opencode.db file lock was released (could now delete it)
- Replaced old DB with repaired copy
- Removed
OPENCODE_DB env var
- PowerShell 7.1 TUI now works — in the same tab that was crashing minutes earlier, without any shell restart
Step 7: Restoration and verification
All workaround measures were reverted:
OPENCODE_DB env var removed
.bashrc OPENCODE_DB export removed
- Repaired database placed at standard location (
opencode.db)
OPENCODE_DISABLE_MOUSE=1 kept as preventive measure
OpenCode now works normally in all terminals (PowerShell 7.1, CMD, Git Bash).
Root Cause Analysis (Three-Layer Model)
Layer 1: The initial crash
The first crash that triggered the entire chain was likely a Bun segfault on Windows. Evidence:
The v1.18.4 upgrade had an EPERM error (could not unlink old opencode.exe), which may have left the binary in a partially-corrupted state, contributing to instability.
Layer 2: Database corruption cascade
When OpenCode hard-crashed:
- The SQLite WAL file contained un-checkpointed writes → WAL corruption
- The opencode.exe process died without calling
CloseHandle() on the database file
- Windows marked the file handle as a zombie — the process is dead but the kernel hasn't released the lock
- Every subsequent OpenCode launch attempted to open the database → hit the zombie lock → silently exited
Layer 3: PowerShell 7.1's process model amplifies the problem
This is the most interesting finding and the unreported aspect of this bug:
PowerShell 7.1 appears to use a different console/PTY process architecture than cmd.exe. When a child process (opencode.exe / Bun) hard-crashes under PowerShell:
- The zombie file handle seems to be retained within PowerShell's process tree
- Even restarting the terminal tab doesn't fully release it (the handle may persist in the Windows console session)
cmd.exe uses a simpler, more isolated process model that is not affected
When OpenCode runs successfully from cmd.exe and exits normally:
- SQLite performs automatic WAL recovery on the database
- The normal exit path calls proper cleanup (
CloseHandle, win32FlushInputBuffer)
- The zombie handle is somehow forced-released by the kernel
- All terminals can now access the database normally
This is why "just run it from CMD once" fixes everything.
Workaround / Fix
Immediate fix (no reboot needed)
:: Open a CMD terminal (not PowerShell)
set OPENCODE_DISABLE_MOUSE=1
opencode --pure
:: Type /exit to quit normally
:: Now PowerShell should work again
Full repair (if the above doesn't suffice)
:: 1. Remove corrupted WAL
del %USERPROFILE%\.local\share\opencode\opencode.db-wal
del %USERPROFILE%\.local\share\opencode\opencode.db-shm
:: 2. Reinstall OpenCode
npm uninstall -g opencode-ai
npm install -g opencode-ai
:: 3. Launch from CMD once
set OPENCODE_DISABLE_MOUSE=1
opencode --pure
:: Type /exit
Preventive measure
Set OPENCODE_DISABLE_MOUSE=1 as a persistent Windows user environment variable to reduce the probability of future TUI-related crashes.
Other observations
opencode web mode works even when TUI is broken — useful as a fallback
opencode run "message" (headless) works more reliably than TUI — can be used for quick testing
opencode serve mode also crashes silently, possibly related to #38220 (Bun HTTP server on Windows)
- Database was 57MB with 11 sessions, 316 messages, 1319 parts — all data preserved after repair
- CJK characters in working directory path did not cause any issues
Diagnostic Commands Reference
# Check OpenCode paths
opencode debug paths
# Check database integrity (Python)
python -c "
import sqlite3
conn = sqlite3.connect(r'%USERPROFILE%\.local\share\opencode\opencode.db')
c = conn.cursor()
c.execute('PRAGMA integrity_check')
print(c.fetchone())
c.execute('PRAGMA wal_checkpoint(TRUNCATE)')
print(c.fetchall())
conn.close()
"
# Check if database is locked (PowerShell)
$f = "$env:USERPROFILE\.local\share\opencode\opencode.db"
try {
$fs = [IO.File]::Open($f, [IO.FileMode]::Open, [IO.FileAccess]::ReadWrite, [IO.FileShare]::None)
$fs.Close(); Write-Host 'Not locked'
} catch { Write-Host "Locked: $_" }
# Find OPENCODE_* env vars supported by the binary
strings opencode.exe | grep -oP 'OPENCODE_[A-Z_]+' | sort -u
Related Issues
| Issue |
Relation |
| #24288 |
Windows mouse escape sequence leak — likely contributed to initial crash |
| #8785 |
Bun segfault on Windows — likely root cause of the first crash |
| #35847 |
Bun panic (Illegal instruction) on Windows 11 |
| #34940 |
Terminal corruption after /exit |
| #38220 |
Windows serve/web HTTP not accepting connections under Bun |
| #37416 |
Mouse text selection crashes TUI on Windows 11 |
Hard-to-reproduce note
This bug is difficult to reproduce on demand because it requires:
- A Bun hard crash during normal OpenCode use (itself non-deterministic on Windows)
- The crash must occur in PowerShell 7.1 specifically
- The resulting zombie handle state is invisible to normal diagnostic tools
However, the diagnostic signature is clear: if OpenCode works from CMD but not from PowerShell, this bug is the cause. The fix is immediate and reliable.
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Description
Bug Report: After a hard crash in PowerShell, OpenCode database lock persists until OpenCode runs successfully from CMD
Environment
npm install -g opencode-aiSymptoms
TUI crashes instantly — window flashes, alternate screen buffer activates briefly (escape sequences visible), then exits silently with exit code 0. No error message, no stack trace.
Mouse escape sequences flood the terminal after crash — the TUI's mouse capture mode remains active and raw ANSI sequences are written to the terminal.
opencode run "message"initially works, but subsequently also exits silently (exit code 0, zero output).opencode session list,opencode stats,opencode debug info— all exit code 0 with zero bytes on stdout and stderr.opencode --version,opencode debug paths,opencode debug startup— these continue to work. They are the only commands that don't require database access.opencode servedies immediately (no log output produced).Restarting the terminal does NOT fix the problem. Only rebooting the machine temporarily resolves it.
The critical clue: Launching OpenCode from
cmd.exeworks. After a successfulcmd.exesession exits normally, PowerShell also starts working again — in the same PowerShell tab that previously crashed, without restarting the shell process.Full Debugging Journey
Step 1: Initial suspicion — mouse tracking corruption
Checked logs at
%USERPROFILE%\.local\share\opencode\log\opencode.log. Alllevel=ERRORentries wereerror=Aborted stack=undefined, which turned out to be user-initiated Ctrl+C interrupts, not crashes. The actual crash produced no log entry at all — characteristic of a Bun-level hard crash (SIGSEGV/SIGILL).Found issue #24288 about Windows mouse escape sequence leakage. Verified that
OPENCODE_DISABLE_MOUSEis an officially recognized env var by extracting strings from the 173MBopencode.exebinary:Set
OPENCODE_DISABLE_MOUSE=1as a Windows user environment variable. Mouse flooding stopped, but TUI still crashed. This ruled out mouse tracking as the primary cause.Step 2: Database integrity check
Headless mode (
opencode run "message") worked fine. This meant the core engine and AI provider were functional. The crash was specific to TUI and server mode initialization.Ran SQLite integrity check on the database (57MB) via Python:
Key finding: The main database file was intact (
integrity_check: ok), but the WAL (Write-Ahead Log) was corrupted. Thewal_checkpointconsistently failed withdisk I/O error.Step 3: The database lock discovery
Attempted to VACUUM the database into a repaired copy. The VACUUM succeeded on a temp copy (57.7MB → 57.5MB, integrity verified), but could not replace the original file:
Further investigation revealed:
del /F opencode.db→ "Access is denied"ren opencode.db opencode.db.old→ "Access is denied"[IO.File]::OpenwithFileShare.None→ Succeeds (file CAN be opened for I/O)Conclusion: The file is not locked by another process in the traditional sense. It's a zombie file handle — the process that held it open has crashed, but Windows has not released the handle. This is a kernel-level orphaned lock that survives process termination but not reboots.
Step 4: Workaround with OPENCODE_DB env var
Used the
OPENCODE_DBenv var (also found in the binary strings) to point OpenCode to the repaired database at a different filename:opencode runworked again. But TUI andservestill crashed. This proved database access was necessary but not sufficient for TUI recovery.Step 5: Binary reinstall
The upgrade log showed an EPERM error during the 1.18.3→1.18.4 upgrade:
The old binary could not be replaced because it was in use. A subsequent downgrade may have encountered the same issue in reverse. Performed a clean reinstall:
After reinstall,
opencode runworked consistently. But TUI still crashed in PowerShell.Step 6: The PowerShell vs CMD discovery
At this point, a hypothesis emerged: PowerShell's PTY/process model might be preventing proper cleanup of the zombie file handle.
Tested from
cmd.exe:cmd.exeTUI launched successfully. After exiting normally:opencode.dbfile lock was released (could now delete it)OPENCODE_DBenv varStep 7: Restoration and verification
All workaround measures were reverted:
OPENCODE_DBenv var removed.bashrcOPENCODE_DBexport removedopencode.db)OPENCODE_DISABLE_MOUSE=1kept as preventive measureOpenCode now works normally in all terminals (PowerShell 7.1, CMD, Git Bash).
Root Cause Analysis (Three-Layer Model)
Layer 1: The initial crash
The first crash that triggered the entire chain was likely a Bun segfault on Windows. Evidence:
The v1.18.4 upgrade had an EPERM error (
could not unlink old opencode.exe), which may have left the binary in a partially-corrupted state, contributing to instability.Layer 2: Database corruption cascade
When OpenCode hard-crashed:
CloseHandle()on the database fileLayer 3: PowerShell 7.1's process model amplifies the problem
This is the most interesting finding and the unreported aspect of this bug:
PowerShell 7.1 appears to use a different console/PTY process architecture than
cmd.exe. When a child process (opencode.exe / Bun) hard-crashes under PowerShell:cmd.exeuses a simpler, more isolated process model that is not affectedWhen OpenCode runs successfully from
cmd.exeand exits normally:CloseHandle,win32FlushInputBuffer)This is why "just run it from CMD once" fixes everything.
Workaround / Fix
Immediate fix (no reboot needed)
Full repair (if the above doesn't suffice)
Preventive measure
Set
OPENCODE_DISABLE_MOUSE=1as a persistent Windows user environment variable to reduce the probability of future TUI-related crashes.Other observations
opencode webmode works even when TUI is broken — useful as a fallbackopencode run "message"(headless) works more reliably than TUI — can be used for quick testingopencode servemode also crashes silently, possibly related to #38220 (Bun HTTP server on Windows)Diagnostic Commands Reference
Related Issues
Hard-to-reproduce note
This bug is difficult to reproduce on demand because it requires:
However, the diagnostic signature is clear: if OpenCode works from CMD but not from PowerShell, this bug is the cause. The fix is immediate and reliable.
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response