tursodatabase/turso · error · RangeError
The supplied SQL string contains no statements
Error message
The supplied SQL string contains no statements
What it means
Thrown by Database.prepare() when the SQL argument is falsy (empty string, null, undefined). This mirrors better-sqlite3's RangeError for empty statements: preparing nothing is a programming error, not a SQL error, so the compat layer rejects it before ever reaching the native engine.
Source
Thrown at bindings/javascript/packages/common/compat.ts:162
name: { get: () => this.db.path },
readonly: { get: () => this.db.readonly },
open: { get: () => this.db.open },
memory: { get: () => this.db.memory },
inTransaction: { get: () => this.db.inTransaction() },
});
}
/**
* Prepares a SQL statement for execution.
*
* @param {string} sql - The SQL statement string to prepare.
*/
prepare(sql) {
if (!this.open) {
throw new TypeError("The database connection is not open");
}
if (!sql) {
throw new RangeError("The supplied SQL string contains no statements");
}
try {
return new Statement(this.db.prepare(sql), this.db);
} catch (err) {
throw convertError(err);
}
}
/**
* Returns a function that executes the given function in a transaction.
*
* @param {function} fn - The function to wrap in a transaction.
*/
transaction(fn) {
if (typeof fn !== "function")
throw new TypeError("Expected first argument to be a function");
View on GitHub (pinned to bad083fafb)
Solutions
- Guard before preparing: if (!sql) skip or throw your own descriptive error
- Filter blank statements when building dynamic SQL: parts.filter(Boolean).join(' ')
- Trim and validate user/config-provided SQL before it reaches prepare()
- Check for typos or missing properties when the SQL comes from destructured objects
Example fix
// before
const sql = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
db.prepare(`SELECT * FROM t ${sql}`); // fine
const stmt = db.prepare(buildQuery()); // buildQuery() returned '' -> RangeError
// after
const sqlText = buildQuery() ?? '';
if (!sqlText.trim()) throw new Error('buildQuery() produced no SQL');
const stmt = db.prepare(sqlText); Defensive patterns
Strategy: validation
Validate before calling
function prepareSql(db: Database, sql: string | undefined | null) {
if (typeof sql !== 'string' || sql.trim() === '') {
throw new RangeError('SQL string is empty');
}
return db.prepare(sql);
} Type guard
function isNonEmptySql(sql: unknown): sql is string {
return typeof sql === 'string' && sql.trim().length > 0;
} Try / catch
try {
stmt = db.prepare(sql);
} catch (err) {
if (err instanceof RangeError && err.message.includes('no statements')) {
// Programming error: log loudly with the origin of the SQL, never retry silently
throw new Error(`Empty SQL produced by ${sourceLocation}`);
}
throw err;
} Prevention
- Filter dynamic SQL fragments with .filter(Boolean) before joining
- Validate config/file-derived SQL lists for blank entries at load time
- Fail fast in dev with your own descriptive error so the origin is obvious
When it happens
Trigger: Calling db.prepare(''), db.prepare(null), or db.prepare(undefined); building SQL by string concatenation where an optional clause leaves an empty string; looping over a list of queries that contains an empty entry; passing a variable that was never assigned (typo'd identifier resolving to undefined).
Common situations: Dynamic query builders that join zero conditions into ''; config-driven SQL lists with blank lines not filtered; destructuring a missing property (const { sql } = row where row.sql is undefined) and passing it straight to prepare().
Related errors
- Expected first argument to be a function
- Expected first argument to be a string
- Expected second argument to be an options object
- Expected first argument to be an array of statements
- The database connection is not open
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/35827fbce6b183b3.
Report an issue: GitHub.