Repository navigation
Description
Before submitting
- I searched the open and closed issues for a related report.
- I removed credentials, tokens, private paths, and sensitive target data.
Area
Evidence, artifacts, or reconstruction
Observed behavior
On Windows, when another process holds the selected file open without read sharing, Node's read fails with EBUSY. inspect_sqlite_database reports it as a generic execution failure that tells the caller not to retry:
code: execution_failure category: execution_failure retryable: false
message: Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.
details.diagnostics.reason: EBUSY: resource busy or locked, open '<temp>\exclusive.sqlite'
The unchanged request succeeds as soon as the other process closes the file, so both the retry guidance and the rea doctor hint are wrong for this case.
Reproduction
- Create any SQLite database, for example
exclusive.sqlite. - In another PowerShell window, hold it open without sharing:
$f = [System.IO.File]::Open('<path>\exclusive.sqlite', 'Open', 'ReadWrite', 'None'). - Run
rea inspect-sqlite-database <path>\exclusive.sqlite --json: the output above, exit code 1. - Run
$f.Close()and repeat step 3: it succeeds.
Expected behavior
A distinct outcome that says the selected file is in use by another process, marks the request as retryable once that process releases it, and suggests closing the owning application or inspecting a copy.
Impact and scope
Any caller on Windows that inspects a database an application keeps open without read sharing gets a misleading, non-retryable error. POSIX hosts rarely return EBUSY for regular file reads, so this is mostly a Windows problem.
The same misclassification likely applies beyond SQLite: about 22 providers map EACCES/EPERM on selected-file reads to AnalysisAccessDeniedError (for example src/sqlite/SqliteDatabaseFailures.ts, src/pcap/PcapSnapshot.ts, src/go/GoBinaryProvider.ts), and none maps EBUSY.
REA version
Source build of main at 117bd23dd.
Runtime and platform
Windows 11 x64 (10.0.26300), non-elevated, Node 24.18.0, local NTFS volume, Windows native addon built from the same commit.
Target and artifact context
A small benign SQLite database created for the test (rollback journal mode, one table).
Interface
CLI
Earliest failure stage
Transport or result projection
Relevant output or evidence
See "Observed behavior". In src/sqlite/SqliteDatabaseFailures.ts, the artifact-read phase maps EACCES/EPERM to AnalysisAccessDeniedError and ENOENT/ENOTDIR to an input error; any other code, including EBUSY, falls through to ProviderAdapterError, which projects as execution_failure with retryable: false.
Typed outcome or recovery expected
An unavailable outcome with retryable: true and a remediation to close the owning process or inspect a copy, in line with how #2467 treats transient Windows sharing conflicts in REA's own runtime paths.
Analysis or suspected cause
EBUSY is not part of the selected-file read error mapping in any provider. Would you prefer a shared mapping for selected-file read errors, or a first PR that handles EBUSY in the SQLite provider only? I can do either.
Additional context
Found while verifying inspect_sqlite_database (#2271) on native Windows, which CI does not cover. Everything else I tried worked: paths with spaces and non-ASCII characters, a WAL left by a writer that exited without closing (WAL included in the result), a live writer, a read-only file and a 317-character path. A hot rollback journal was rejected with a clear message, and no run left rea-sqlite-database-* directories in %TEMP%. Two SQLite boundary tests that fail on Windows for test-only reasons are fixed in a separate PR.
Activity
morluto commentedon Oct 14, 2026
Resolved on main by 664c669.
Selected SQLite database/WAL EBUSY failures are now retryable busy outcomes. The current check injects the boundary failure; no Windows exclusive-lock workload is claimed.
Rechecked on main b8510ee in the current focused run: 20 test files passed, 225 tests passed and one platform-dependent test skipped. Relevant regression coverage: tests/boundary/sqlite/sqliteDatabaseBusy.test.ts.