drizzle-team/drizzle-orm · error · Error
Warning: You need to pass an instance of Client: import { C
Error message
Warning: You need to pass an instance of Client:
import { Client } from "@planetscale/database";
const client = new Client({
host: process.env["DATABASE_HOST"],
username: process.env["DATABASE_USERNAME"],
password: process.env["DATABASE_PASSWORD"],
});
const db = drizzle(client);
What it means
The PlanetScale serverless driver's construct() function guards that the first argument to drizzle() is an actual instance of @planetscale/database Client (checked via `instanceof Client`). Passing a config object, a fetcher, a connection URL string, or any other value fails the instanceof check and throws this descriptive error. The message itself is the fix template showing how to construct the Client correctly.
Source
Thrown at drizzle-orm/src/planetscale-serverless/driver.ts:41
export class PlanetScaleDatabase<
TSchema extends Record<string, unknown> = Record<string, never>,
> extends MySqlDatabase<PlanetscaleQueryResultHKT, PlanetScalePreparedQueryHKT, TSchema> {
static override readonly [entityKind]: string = 'PlanetScaleDatabase';
}
function construct<
TSchema extends Record<string, unknown> = Record<string, never>,
TClient extends Client = Client,
>(
client: TClient,
config: DrizzleConfig<TSchema> = {},
): PlanetScaleDatabase<TSchema> & {
$client: TClient;
} {
// Client is not Drizzle Object, so we can ignore this rule here
// eslint-disable-next-line no-instanceof/no-instanceof
if (!(client instanceof Client)) {
throw new Error(`Warning: You need to pass an instance of Client:
import { Client } from "@planetscale/database";
const client = new Client({
host: process.env["DATABASE_HOST"],
username: process.env["DATABASE_USERNAME"],
password: process.env["DATABASE_PASSWORD"],
});
const db = drizzle(client);
`);
}
const dialect = new MySqlDialect({ casing: config.casing });
let logger;
if (config.logger === true) {
logger = new DefaultLogger();
} else if (config.logger !== false) {View on GitHub (pinned to b7862528fd)
Solutions
- Construct the Client first, then pass it: const client = new Client({host, username, password}); const db = drizzle(client);
- Verify there is only one copy of @planetscale/database installed (check npm ls @planetscale/database / pnpm why) so instanceof resolves to the same class.
- In tests, use the real Client with a mock fetcher rather than a plain object stub, or use Drizzle's schema/dialect test helpers without the driver wrapper.
- Confirm you imported drizzle from drizzle-orm/planetscale-serverless, not another dialect entry point.
Example fix
// before (throws: config object is not a Client instance)
import { drizzle } from 'drizzle-orm/planetscale-serverless';
const db = drizzle({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
});
// after
import { Client } from '@planetscale/database';
import { drizzle } from 'drizzle-orm/planetscale-serverless';
const client = new Client({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
});
const db = drizzle(client); Defensive patterns
Strategy: type-guard
Validate before calling
import { Client } from '@planetscale/database';
function makeDb(client: unknown) {
if (!(client instanceof Client)) {
throw new TypeError('Expected an instance of @planetscale/database Client');
}
return drizzle(client);
}
// Usage:
const client = new Client({ host, username, password });
const db = makeDb(client); Type guard
import { Client } from '@planetscale/database';
function isPlanetScaleClient(v: unknown): v is Client {
return v instanceof Client;
}
// before passing to drizzle:
if (!isPlanetScaleClient(client)) {
throw new Error('drizzle() needs a real Client instance, not a config object');
} Try / catch
try {
const db = drizzle(client as any);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Warning: You need to pass an instance of Client')) {
// re-construct the Client correctly and retry
} else throw e;
} Prevention
- Always construct `new Client({...})` before calling drizzle(); never pass a config object directly.
- Run `npm ls @planetscale/database` in CI to detect duplicate installs that break instanceof.
- In tests, inject the real Client with a mocked fetch rather than a plain object.
When it happens
Trigger: Calling drizzle(configObject) instead of drizzle(new Client(configObject)). Passing process.env.DATABASE_URL or a raw {host,username,password} object. Importing Client from the wrong package or a mock Client in tests. Version mismatch where @planetscale/database exports a different Client class than the one Drizzle imports.
Common situations: Copy-paste from MySQL/Postgres examples where drizzle() accepts a connection URL. Using a singleton Client across Drizzle and raw PlanetScale queries but wrapping it incorrectly. Upgrading @planetscale/database to a version with a changed Client shape, or duplicate installations causing two Client classes.
Related errors
- Transactions are not supported by the Postgres Proxy driver
- Streaming is not supported by the PlanetScale Serverless dri
- You need to specify "mode": "planetscale" or "default" when
- Table "${relation.referencedTable[Table.Symbol.Name]}" not f
- Table "${referencedTableTsName}" not found in schema
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/7e6f2e0d2403b53f.json.
Report an issue: GitHub.