Skip to content

Comments

Fix Windows SQLITE_CANTOPEN by using native path format#6110

Open
penalosa wants to merge 1 commit intomainfrom
penalosa/fix-windows-sqlite-path
Open

Fix Windows SQLITE_CANTOPEN by using native path format#6110
penalosa wants to merge 1 commit intomainfrom
penalosa/fix-windows-sqlite-path

Conversation

@penalosa
Copy link
Contributor

Summary

On Windows, SqliteDatabase::init() in sqlite.c++ constructs the database file path via Vfs::tryAppend(), which returns a kj::Path. The path was serialized with toString(), which is documented as the Unix-style serializer — it always produces forward-slash paths like D:/a/_temp/.../actor.sqlite.

This path is then passed to sqlite3_open_v2() with nullptr VFS, meaning SQLite uses the default win32 VFS which expects native Windows paths with backslashes.

The fix switches to toNativeString(true) which:

  • On Windows: produces D:\a\_temp\...\actor.sqlite (via toWin32String)
  • On non-Windows: is equivalent to toString() (no-op)

The tryAppend() codepath is also Windows-only (returns kj::none on other platforms), so this change is fully scoped to Windows.

Impact

This fixes SQLITE_CANTOPEN errors when using SQLite-backed Durable Objects with Miniflare on Windows. The error manifests at sqlite3_step() (line 1522) rather than sqlite3_open_v2() because the database opens successfully but WAL journal mode (PRAGMA journal_mode=WAL) fails when creating the .sqlite-wal and .sqlite-shm sidecar files.

Discovered while working on vitest-pool-workers v4 support in workers-sdk (cloudflare/workers-sdk#11632).

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 19, 2026

Merging this PR will degrade performance by 16.23%

❌ 1 regressed benchmark
✅ 69 untouched benchmarks
⏩ 129 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
jsonResponse[Response] 39.9 µs 47.6 µs -16.23%

Comparing penalosa/fix-windows-sqlite-path (64ba726) with main (fe9c1a6)2

Open in CodSpeed

Footnotes

  1. 129 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (1052d2e) during the generation of this report, so fe9c1a6 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

penalosa added a commit to cloudflare/workers-sdk that referenced this pull request Feb 19, 2026
workerd's Windows SQLite VFS uses kj::Path::toString() which produces
Unix-style forward-slash paths, causing SQLITE_CANTOPEN with the win32
VFS (cloudflare/workerd#6110). Instead of excluding SQLite DO fixtures
on Windows, use unsafeEphemeralDurableObjects to switch all DOs to
in-memory storage. This avoids disk SQLite paths entirely while keeping
DOs fully functional (including SQLite-backed ones). Cross-restart
persistence isn't needed for tests.
penalosa added a commit to cloudflare/workers-sdk that referenced this pull request Feb 19, 2026
All disk-backed DOs use SQLite internally (regardless of enableSql),
which hits the Windows path bug (cloudflare/workerd#6110). Make the
runner DO ephemeral to avoid disk storage entirely — it doesn't need
persistent state. Switch from getByName() to idFromName()+get() since
ephemeral namespace proxies don't expose getByName.
@penalosa penalosa marked this pull request as ready for review February 23, 2026 21:54
@penalosa penalosa requested review from a team as code owners February 23, 2026 21:54
On Windows, SqliteDatabase::init() constructs the database path via
tryAppend() which returns a kj::Path. The path was serialized with
toString() which produces Unix-style forward-slash paths (e.g.
D:/a/_temp/.../actor.sqlite). This path is passed to sqlite3_open_v2()
with nullptr VFS, meaning SQLite uses the default win32 VFS which
expects native Windows paths.

Switch to toNativeString(true) which produces proper Windows paths
with backslashes (D:\a\_temp\...\actor.sqlite). On non-Windows
platforms, toNativeString() is equivalent to toString(), so this
change is a no-op there. The tryAppend() codepath is also
Windows-only (returns kj::none on other platforms), so the change
is fully scoped.

This fixes SQLITE_CANTOPEN errors when using SQLite-backed Durable
Objects with Miniflare on Windows.
@penalosa penalosa force-pushed the penalosa/fix-windows-sqlite-path branch from 488a316 to 64ba726 Compare February 23, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants