Fix Windows SQLITE_CANTOPEN by using native path format#6110
Open
Fix Windows SQLITE_CANTOPEN by using native path format#6110
Conversation
Merging this PR will degrade performance by 16.23%
Performance Changes
Comparing Footnotes
|
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.
kentonv
approved these changes
Feb 23, 2026
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.
488a316 to
64ba726
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On Windows,
SqliteDatabase::init()insqlite.c++constructs the database file path viaVfs::tryAppend(), which returns akj::Path. The path was serialized withtoString(), which is documented as the Unix-style serializer — it always produces forward-slash paths likeD:/a/_temp/.../actor.sqlite.This path is then passed to
sqlite3_open_v2()withnullptrVFS, meaning SQLite uses the defaultwin32VFS which expects native Windows paths with backslashes.The fix switches to
toNativeString(true)which:D:\a\_temp\...\actor.sqlite(viatoWin32String)toString()(no-op)The
tryAppend()codepath is also Windows-only (returnskj::noneon other platforms), so this change is fully scoped to Windows.Impact
This fixes
SQLITE_CANTOPENerrors when using SQLite-backed Durable Objects with Miniflare on Windows. The error manifests atsqlite3_step()(line 1522) rather thansqlite3_open_v2()because the database opens successfully but WAL journal mode (PRAGMA journal_mode=WAL) fails when creating the.sqlite-waland.sqlite-shmsidecar files.Discovered while working on vitest-pool-workers v4 support in workers-sdk (cloudflare/workers-sdk#11632).