drizzle-team/drizzle-orm · error · Error
Streaming is not supported by the PlanetScale Serverless…
Error message
Streaming is not supported by the PlanetScale Serverless driver
What it means
PlanetscalePreparedQuery.iterator() throws because the PlanetScale serverless driver (@planetscale/database) executes whole queries over HTTP and does not expose a server-side cursor/stream. Drizzle's iterator() override fails fast to make the limitation explicit rather than buffering silently.
Solutions
- Use .all()/.execute() and process the returned array in chunks in application code; PlanetScale serverless returns the full result set.
- Add LIMIT/OFFSET or keyset pagination to bound result size rather than relying on streaming.
- If true streaming is required, switch to a driver that supports cursors (mysql2 over a TCP connection).
Example fix
// before (throws)
const stmt = db.select().from(users).prepare();
for await (const row of stmt.iterator()) { /* ... */ }
// after
const rows = await db.select().from(users).all();
for (const row of rows) { /* ... */ } Defensive patterns
Strategy: validation
Validate before calling
// Do not call iterator() on PlanetScale-serverless prepared queries.
import { entityKind } from 'drizzle-orm/entity';
function supportsIterator(db: any): boolean {
const sessionKind = db?.session?.[entityKind];
return sessionKind !== 'PlanetscaleSession';
}
const result = supportsIterator(db)
? (async () => { for await (const r of stmt.iterator()) yield r; })()
: await stmt.all(); Type guard
function isPlanetScaleServerless(db: any): boolean {
return db?.session?.[Symbol.for('drizzle:entityKind')] === 'PlanetscaleSession';
} Try / catch
try {
for await (const row of stmt.iterator()) { /* ... */ }
} catch (e) {
if (e instanceof Error && /Streaming is not supported by the PlanetScale Serverless driver/.test(e.message)) {
const rows = await stmt.all();
for (const row of rows) { /* ... */ }
} else throw e;
} Prevention
- Avoid .iterator() in shared code paths; use .all() for cross-driver compatibility.
- Paginate large result sets explicitly with LIMIT/OFFSET or keyset pagination.
- Encapsulate result-set access behind a function so the streaming/non-streaming choice is centralized.
When it happens
Trigger: Calling .iterator() on a prepared query or a select built from a PlanetScale-serverless Drizzle database, e.g. for await (const row of db.select().from(t).prepare().iterator()) {}. Also any cursor-based pagination helper that calls iterator() under the hood.
Common situations: Porting code from mysql2 streaming cursors to PlanetScale serverless. Large-result-set processing where a developer reaches for streaming to control memory, not realizing the HTTP driver returns the full set.
Related errors
- Warning: You need to pass an instance of Client: import
- Method not implemented.
- Streaming is not supported by the MySql Proxy driver
- Streaming is not supported by the SingleStore Proxy driver
- Transactions are not supported by the Postgres Proxy driver
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /api/errors/bbd61047a1d6ae9c.
Report an issue: GitHub.
Appendix: source
Thrown at drizzle-orm/src/planetscale-serverless/session.ts:109
j++;
}
return returningResponse;
}
return res;
}
const { rows } = await this.queryWithCache(queryString, params, async () => {
return await client.execute(queryString, params, query);
});
if (customResultMapper) {
return customResultMapper(rows as unknown[][]);
}
return rows.map((row) => mapResultRow<T['execute']>(fields!, row as unknown[], joinsNotNullableMap));
}
override iterator(_placeholderValues?: Record<string, unknown>): AsyncGenerator<T['iterator']> {
throw new Error('Streaming is not supported by the PlanetScale Serverless driver');
}
}
export interface PlanetscaleSessionOptions {
logger?: Logger;
cache?: Cache;
}
export class PlanetscaleSession<
TFullSchema extends Record<string, unknown>,
TSchema extends TablesRelationalConfig,
> extends MySqlSession<MySqlQueryResultHKT, PlanetScalePreparedQueryHKT, TFullSchema, TSchema> {
static override readonly [entityKind]: string = 'PlanetscaleSession';
private logger: Logger;
private client: Client | Transaction | Connection;
private cache: Cache;
View on GitHub (pinned to b7862528fd)