Skip to content

drizzle: statically typed db.execute / db.transaction throws "Cannot convert undefined or null to object" on main (0.5.1519 ok; db: any ok) #9516

Description

@proggeramlug

Summary

On main (f1e9c37) a statically typed drizzle database object throws on its first call:

TypeError: Cannot convert undefined or null to object
    at <anonymous>

The same program with const db: any = drizzle(pool, { mode: "default" }) runs fine, and db.session.execute(q) / db.session.prepareQuery(...).execute() work either way. perry 0.5.1519 runs the typed form. Found while reproducing #9356; it blocks that issue's repro script on main.

Reproduction

npm i drizzle-orm@0.44.7 mysql2@3.24.2, a MySQL on 127.0.0.1:

import mysql from "mysql2/promise";
import { drizzle } from "drizzle-orm/mysql2";
import { sql } from "drizzle-orm";

const pool = mysql.createPool({ host: "127.0.0.1", port: 3306, user: "root", password: "", database: "test" });
const db = drizzle(pool, { mode: "default" });          // typed: MySql2Database & { $client }
try {
  await db.execute(sql`SELECT 1 AS x`);                  // TypeError on main
  console.log("ok");
} catch (e) { console.log(String(e)); }
toolchain const db = drizzle(...) (typed) const db: any = drizzle(...)
0.5.1519 (23a2113) ok ok
main f1e9c37 TypeError: Cannot convert undefined or null to object ok

db.transaction(async (tx) => …) fails the same way. db.session.execute(q), db.session.prepareQuery(dialect.sqlToQuery(q), undefined, undefined, false).execute(), Object.keys(db), Object.keys(db.session) all succeed on main with the typed object, so the failure is in how the typed db.execute / db.transaction member call is lowered (the return type of drizzle() is an intersection MySql2Database<TSchema> & { $client: … }), not in drizzle's own code. Same TypeError with compilePackages: ["drizzle-orm"] set.

A second variant: in a pnpm layout (node_modules/drizzle-orm -> ../../../node_modules/.pnpm/drizzle-orm@0.44.7_…/node_modules/drizzle-orm, the reporter's app tree) even the db: any form throws the same TypeError on both toolchains, so module resolution changes which drizzle build gets compiled there. Both variants are perrymaster-reproducible (/root/claude-9356/repro/drz2.ts and /root/claude-9356/intree/).

Where

Bisect list (313 commits, 23a2113..f1e9c37); the typed-dispatch commits in that range are the obvious first suspects: #9479 (root the dynamic-dispatch receiver across its argument list), #9472 (static this is the constructor), #9444 (accessor call must not corrupt the caller's this).

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