Enforce read-only mode when opening Bun SQLite databases - #6993
Conversation
🦋 Changeset detectedLatest commit: 14ee79b The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Important
This PR currently only adds failing reproduction tests; it doesn't include the SqliteClient implementation fix described in the PR body. Please push the implementation change before merging, and address the test-coverage notes below.
Reviewed changes
packages/sql/sqlite-bun/test/Client.test.ts: replaces the placeholder@effect/vitesttest withbun:testtests, including a focused reproduction for readonly clients rejecting writes.
⚠️ Still needs a SqliteClient implementation fix
The PR title and body say the implementation fix should be added to the same branch, but only the test file changed. The root cause is in packages/sql/sqlite-bun/src/SqliteClient.ts:118-122: readwrite is defaulted to true independently of readonly, so Bun opens the database writable even when readonly: true is requested.
I wouldn't block merging on the missing fix since the PR body describes it as a deliberate two-stage branch, but the branch isn't mergeable in this state.
⚠️ Test uses a loose assertion that bypasses many failures
await expect(write).rejects.toBeDefined() passes for any rejected promise, including connection failures, scope errors, or the finalizer failing to clean up. The test should assert that the rejection is specifically the SQLite read-only error, ideally by checking the error type thrown by bun:sqlite or by asserting on the SqlError cause.
ℹ️ Test framework choice departs from repo conventions
The rest of the Effect SQL packages use @effect/vitest with it.effect and assert (see packages/sql/sqlite-node/test/Client.test.ts) and repo guidance in .patterns/testing.md recommends the same. Switching this file to bun:test/expect/Effect.runPromise should either be reverted to match the repo pattern or justified in a comment if this package intentionally uses Bun's native runner.
ℹ️ Prefer Effect-native error assertion instead of async/await
The test mixes async/await and Effect.runPromise. The repository conventions prefer it.effect and assert from @effect/vitest; the readonly rejection can be asserted with Effect.either, Effect.catchAll, or Effect.flip without leaving the Effect runtime.
@v0 or keep the SHA fresh with Dependabot | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
| yield* sql`INSERT INTO test DEFAULT VALUES` | ||
| }) | ||
| ).pipe(Effect.provide(Reactivity.layer), Effect.runPromise) | ||
| await expect(write).rejects.toBeDefined() |
There was a problem hiding this comment.
This assertion is too loose — rejects.toBeDefined() passes for any rejection. Please assert that the failure is specifically the SQLite read-only error, e.g. by checking the error message/cause.
| @@ -1,6 +1,28 @@ | |||
| import { describe, it } from "@effect/vitest" | |||
| import { Database } from "bun:sqlite" | |||
| import { describe, expect, test } from "bun:test" | |||
There was a problem hiding this comment.
Sibling packages and .patterns/testing.md use @effect/vitest with it.effect and assert. Is there a reason this file needs bun:test? If not, revert to the repo convention.
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|

Summary
A client created with readonly: true permits writes under the default configuration.
Important
This PR starts with focused failing reproduction tests. Add the implementation fix to this same branch; CI is expected to fail until that fix is included.
readonly mode still opens a writable database
Module:
sqlite-bun/SqliteClientAudit ID:
sql-adapters-sb-1Severity / confidence: high / high
What happens
A client created with readonly: true permits writes under the default configuration.
Why it happens
Construction passes readonly: true while independently defaulting readwrite to true, and Bun's read/write flag wins.
Expected behavior
SqliteClientConfig.readonly must enforce the public read-only open mode.
Relevant implementation
These links and excerpts are pinned to audit base
c9b56ab507f224426ee8388dc450da447ec4715f.packages/sql/sqlite-bun/src/SqliteClient.ts:117-127View problematic code at
packages/sql/sqlite-bun/src/SqliteClient.ts:117-127View exact lines on GitHub
Reproduction
bun test packages/sql/sqlite-bun/test/Client.test.tsObserved failure: A write through the readonly client completed successfully.
Implementation handoff
The initial reproduction tests on this branch are the regression specification for the implementation fix that should follow in this PR.
bun test packages/sql/sqlite-bun/test/Client.test.tsAudit provenance
c9b56ab507f224426ee8388dc450da447ec4715f8f9499f562729f5f7b08d8bcc4db86b4aeff8a21sql-adapters-sb-1Closes EFF-430