drizzle-team/drizzle-orm · error · Error

Transactions are not supported by the MySql Proxy driver

Error message

Transactions are not supported by the MySql Proxy driver

What it means

A plain Error 'Transactions are not supported by the MySql Proxy driver' thrown by MySqlRemoteSession.transaction() (drizzle-orm/src/mysql-proxy/session.ts:89). The mysql-proxy adapter (drizzle-orm/mysql-proxy) talks to a remote callback over the wire and intentionally has no transaction implementation — calling db.transaction() always throws synchronously.

Source

Thrown at drizzle-orm/src/mysql-proxy/session.ts:89

			cacheConfig,
			fields,
			customResultMapper,
			generatedIds,
			returningIds,
		) as PreparedQueryKind<MySqlRemotePreparedQueryHKT, T>;
	}

	override all<T = unknown>(query: SQL): Promise<T[]> {
		const querySql = this.dialect.sqlToQuery(query);
		this.logger.logQuery(querySql.sql, querySql.params);
		return this.client(querySql.sql, querySql.params, 'all').then(({ rows }) => rows) as Promise<T[]>;
	}

	override async transaction<T>(
		_transaction: (tx: MySqlProxyTransaction<TFullSchema, TSchema>) => Promise<T>,
		_config?: MySqlTransactionConfig,
	): Promise<T> {
		throw new Error('Transactions are not supported by the MySql Proxy driver');
	}
}

export class MySqlProxyTransaction<
	TFullSchema extends Record<string, unknown>,
	TSchema extends TablesRelationalConfig,
> extends MySqlTransaction<MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT, TFullSchema, TSchema> {
	static override readonly [entityKind]: string = 'MySqlProxyTransaction';

	override async transaction<T>(
		_transaction: (tx: MySqlProxyTransaction<TFullSchema, TSchema>) => Promise<T>,
	): Promise<T> {
		throw new Error('Transactions are not supported by the MySql Proxy driver');
	}
}

export class PreparedQuery<T extends MySqlPreparedQueryConfig> extends PreparedQueryBase<T> {
	static override readonly [entityKind]: string = 'MySqlProxyPreparedQuery';

View on GitHub (pinned to b7862528fd)

Solutions

  1. Switch to a driver that supports transactions: drizzle-orm/mysql2 with a real Pool for serverful apps.
  2. If you must stay on the proxy, restructure logic to avoid transactions (single statements, or server-side transaction endpoints invoked via the remote callback).
  3. Remove or guard all db.transaction() call sites when adopting mysql-proxy.

Example fix

// before
import { drizzle } from 'drizzle-orm/mysql-proxy';
const db = drizzle(remoteCallback, { schema });
await db.transaction(async (tx) => { /* ... */ }); // throws

// after — use mysql2 driver which supports transactions
import mysql from 'mysql2/promise';
import { drizzle } from 'drizzle-orm/mysql2';
const db = drizzle(mysql.createPool(process.env.DATABASE_URL!), { schema, mode: 'default' });
await db.transaction(async (tx) => { /* ... */ });
Defensive patterns

Strategy: validation

Validate before calling

import { MySqlRemoteSession } from 'drizzle-orm/mysql-proxy';
import type { MySqlDatabase } from 'drizzle-orm/mysql-core';

function supportsTransactions(db: MySqlDatabase<any, any, any, any>): boolean {
  // mysql-proxy uses MySqlRemoteSession whose transaction() throws
  return !(db.session instanceof MySqlRemoteSession);
}

if (!supportsTransactions(db)) {
  throw new Error('This code path requires a transaction-capable MySQL driver (use mysql2).');
}

Type guard

import { MySqlRemoteSession } from 'drizzle-orm/mysql-proxy';

function isProxySession(db: any): boolean {
  return db?.session instanceof MySqlRemoteSession;
}

Try / catch

try {
  await db.transaction(async (tx) => { /* ... */ });
} catch (e) {
  if (e instanceof Error && /not supported by the MySql Proxy driver/i.test(e.message)) {
    // switch to a transaction-capable driver instead of retrying
    throw new Error('Transactions unavailable on mysql-proxy; use drizzle-orm/mysql2.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing the DB with drizzle-orm/mysql-proxy's drizzle(remoteCallback, { schema }) and then calling db.transaction(async tx => { ... }) (with or without a config argument). The override throws immediately.

Common situations: Migrating from mysql2/node-mysql2 to the proxy driver for an edge/serverless HTTP setup and leaving existing db.transaction() call sites in place. The proxy is meant for stateless request/response, so multi-statement transactions are impossible.

Related errors


AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03). Data as JSON: /data/errors/595207b949780546.json. Report an issue: GitHub.