Skip to content

bun:sqlite Database.query() returns undefined when the database is reached through any indirection #10290

Description

@proggeramlug

Parent: #10107 (OpenCode v1.18.30 native bring-up).

Summary

Database.query() from bun:sqlite returns undefined when the database is reached through any indirection — a Map, a function return, a generator — instead of returning a statement. Called directly on a local it works. prepare() on the same receiver works through the same indirections, so this is specific to query.

Silently returning undefined is the damaging part: the caller fails later, on whatever it does with the statement, with no hint that the database call was the problem.

Repro

import { Database } from "bun:sqlite"
const db: any = new Database(":memory:")
db.run("create table t (a integer, b text)")
db.run("insert into t values (1, 'x')")

console.log("direct   ", typeof db.query("select * from t"))

const ctx = new Map<string, any>([["native", db]])
console.log("via Map  ", typeof ctx.get("native").query("select * from t"))

function getNative(): any { return db }
console.log("via fn   ", typeof getNative().query("select * from t"))

function* gen(): any { return db }
function runGen(g: any) { const it = g(); let r = it.next(); while (!r.done) r = it.next(r.value); return r.value }
const viaGen: any = runGen(gen)
console.log("via gen  ", typeof viaGen.query("select * from t"))
console.log("prepare  ", typeof viaGen.prepare("select * from t"))   // control: works

bun 1.3.14 — every line prints object.

perry 0.5.1571 (--platform bun):

direct    object
via Map   undefined
via fn    undefined
via gen   undefined
prepare   object      ← the control passes, so the receiver itself is fine

Second divergence in the same area

The statement's methods are callable but invisible as properties:

const stmt: any = db.prepare("select * from t")
typeof stmt.safeIntegers   // bun: "function"   perry: "undefined"
stmt.safeIntegers(true)    // both: works

Same for a statement obtained from db.query(...). So a direct call dispatches, but typeof, feature detection and destructuring all see nothing. Worth fixing together since both look like the native dispatch table being consulted only on the direct-call shape.

Why it matters

This is what OpenCode's models command hits. packages/core/src/database/sqlite.bun.ts does exactly the failing shape — the database arrives from an effect service through Effect.gen, and then:

const native = (yield* Sqlite.Native) as Database
const statement = native.query(query)
statement.safeIntegers(Context.get(fiber.context, Client.SafeIntegers))

native.query(query) is undefined, so the next line fails with TypeError: Cannot read properties of undefined (reading 'safeIntegers') and the command exits 1.

This path became reachable only after #10281 / PR #10283 taught the resolver to honor the bun export condition. OpenCode maps #sqlite, #db, #pty and #fff by condition:

"#sqlite": { "bun": "./src/database/sqlite.bun.ts", "node": "./src/database/sqlite.node.ts", "default": "./src/database/sqlite.bun.ts" }

Before that fix perry resolved the node variant and never exercised bun:sqlite; the official bun binary has always run the bun variant. So this is a pre-existing gap that the resolver fix uncovered rather than caused — but it does mean models regressed from working to failing on that lineage, which is worth knowing when reading the bring-up status.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions