drizzle-team / drizzle-team/drizzle-orm

[BUG]: drizzle-kit silently prefers a stale transitive `@libsql/client` over `@tursodatabase/serverless`, failing `turso://` URLs with `URL_SCHEME_NOT_SUPPORTED`

Open
#6,163 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### Report hasn't been filed before.

- [x] I have verified that the bug I'm about to report hasn't been filed before.

### What version of `drizzle-orm` are you using?

1.0.0-rc.4

### What version of `drizzle-kit` are you using?

1.0.0-rc.4

### Other packages

@tursodatabase/serverless@1.4.0

### Describe the Bug

**What is the undesired behavior?**

With `dialect: "turso"`, drizzle-kit picks its database driver by probing for installed packages, and it probes `@libsql/client` **before** `@tursodatabase/serverless` (`connectToTursoRemote` in `bin.cjs`):

```js
connectToTursoRemote = async (credentials) => {
if (await checkPackage("@libsql/client")) {
const { createClient } = await import("@libsql/client");
...
```

`checkPackage` answers `true` for *any* resolvable package — including a transitive leftover the project does not directly depend on. In our pnpm monorepo we had migrated the app from `@libsql/client` to the new `@tursodatabase/serverless` SDK, but the lockfile still contained a stale peer resolution (`drizzle-orm` lists `@libsql/client` as an optional peer), so the old client remained in `node_modules`.

As a result, `drizzle-kit migrate` loaded `@libsql/client` — which does not accept the `turso://` scheme that the Turso Cloud dashboard now hands out — and failed in CI with:

```
LibsqlError: URL_SCHEME_NOT_SUPPORTED
```

Meanwhile the application itself connected fine with the exact same URL, because at runtime it uses `@tursodatabase/serverless` (1.4+ normalizes `turso://` → `https://` internally). Debugging this was quite confusing because the turso-remote code path (unlike the local-sqlite path) prints no `Using '...' driver for database querying` info line, so nothing indicated that drizzle-kit had picked a different driver than the app uses.

**What are the steps to reproduce it?**

1. `pnpm add drizzle-orm@1.0.0-rc.4 drizzle-kit@1.0.0-rc.4 @tursodatabase/serverless`
2. Make `@libsql/client` resolvable without being a direct dependency (in our case: a stale lockfile peer-resolution from before the SDK migration; `pnpm add @libsql/client` also reproduces the driver-precedence behavior)
3. `drizzle.config.ts`:
```ts
export default defineConfig({
dialect: "turso",
schema: "./schema.ts",
dbCredentials: {
url: "turso://.turso.io", // as issued by the Turso Cloud dashboard
authToken: "",
},
});
```
4. `npx drizzle-kit push` (or `migrate`) → `LibsqlError: URL_SCHEME_NOT_SUPPORTED`
5. Remove `@libsql/client` from the dependency tree (reinstall `drizzle-orm` so the lockfile drops the stale resolution) → drizzle-kit falls back to `@tursodatabase/serverless` and the same URL works (modulo a separate issue with the bundled copy of that SDK, which I'm filing separately — it will appear as a cross-reference on this issue)

**What is the desired result?**

Any of these would have avoided the failure:

- For `dialect: "turso"`, prefer `@tursodatabase/serverless` / `@tursodatabase/database` (the current-generation SDKs) over `@libsql/client` when both are resolvable — or prefer whichever the project *directly* depends on
- Normalize `turso://` → `https://` in `normaliseSQLiteUrl` before handing the URL to whichever driver was selected (currently it passes any URL with a protocol through unchanged)
- At minimum, print the `Using '...' driver` info line in the turso-remote path too, so the driver choice is visible

**Environment**: pnpm 10 workspace / monorepo, Node.js 22, macOS & Linux (CI), Turso Cloud (remote database).

Contributor guide

Open the contributing guide

Research direction

Start in bin.cjs at connectToTursoRemote and checkPackage, then inspect normaliseSQLiteUrl and the existing driver-info logging. Reproduce with the listed pnpm dependencies and a turso:// URL, comparing behavior when @libsql/client is resolvable versus only @tursodatabase/serverless. Done means the driver selection is appropriate and the reported CI failure no longer occurs.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, sqlite, typescript
Domain
cli, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.