n8n-io/n8n · error · TypeORMError

Stream is not supported by sqlite driver.

Error message

Stream is not supported by sqlite driver.

What it means

SQLite's driver has no streaming result-set support, so AbstractSqliteQueryRunner.stream() unconditionally throws TypeORMError the moment it is called. There is no partial capability — it is always a programming error on this driver.

Source

Thrown at packages/@n8n/typeorm/src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts:169

				this.isTransactionActive = false;
			}

			await this.broadcaster.broadcast('AfterTransactionRollback');
		} catch (rollbackError) {
			throw new TransactionRollbackFailedError(rollbackError);
		}
	}

	/**
	 * Returns raw data stream.
	 */
	stream(
		query: string,
		parameters?: any[],
		onEnd?: Function,
		onError?: Function,
	): Promise<ReadStream> {
		throw new TypeORMError(`Stream is not supported by sqlite driver.`);
	}

	/**
	 * Returns all available database names including system databases.
	 */
	async getDatabases(): Promise<string[]> {
		return Promise.resolve([]);
	}

	/**
	 * Returns all available schema names including system schemas.
	 * If database parameter specified, returns schemas of that database.
	 */
	async getSchemas(database?: string): Promise<string[]> {
		return Promise.resolve([]);
	}

	/**

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Do not call stream() on SQLite — use query() and paginate with LIMIT/OFFSET or iterate the returned rows in memory.
  2. Branch on driver type before choosing the streaming path.
  3. For genuinely large SQLite datasets, switch to an incremental cursor or move the data to a streaming-capable store.

Example fix

// before
await queryRunner.stream('SELECT * FROM big_table');

// after
if (queryRunner.stream === undefined || dataSource.options.type === 'sqlite' || dataSource.options.type === 'sqlite-pooled') {
  const rows = await queryRunner.query('SELECT * FROM big_table LIMIT ? OFFSET ?', [size, offset]);
} else {
  await queryRunner.stream('SELECT * FROM big_table');
}
Defensive patterns

Strategy: validation

Validate before calling

function supportsStreaming(ds: DataSource): boolean {
  const t = ds.options.type;
  return t !== 'sqlite' && t !== 'sqlite-pooled' && t !== 'better-sqlite3';
}

if (supportsStreaming(dataSource)) {
  await queryRunner.stream(sql);
} else {
  const rows = await queryRunner.query(sql);
}

Type guard

const isSqliteRunner = (qr: QueryRunner): boolean =>
  qr.connection.options.type === 'sqlite' ||
  qr.connection.options.type === 'sqlite-pooled';

Prevention

When it happens

Trigger: Calling queryRunner.stream(...) (or any DataSource higher-level API that delegates to streaming) against a SQLite-backed DataSource.

Common situations: Generic repositories/DAOs written for Postgres that assume stream() works on every driver; large-export features that naively reach for streams; copy-pasted code from a PG project.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/7191bbc223676284. Report an issue: GitHub.