tursodatabase/turso · error · Error
Unknown parameter name: ${name}
Error message
Unknown parameter name: ${name} What it means
When bind() receives a single object, bindNamed() iterates its entries and asks the native statement for each parameter's index via namedPosition(). SQLite named parameters carry a :, @, or $ prefix; if the SQL contains no parameter matching the given name (typo, extra key, or prefix-form mismatch), namedPosition returns a negative value and the binding throws 'Unknown parameter name'. The whole bind is rejected before any value is bound.
Source
Thrown at bindings/react-native/src/Statement.ts:89
for (let i = 0; i < params.length; i++) {
const position = i + 1; // 1-indexed
const value = params[i]!;
this.bindValue(position, value);
}
}
/**
* Bind named parameters
*
* @param params - Object with named parameters
*/
private bindNamed(params: Record<string, SQLiteValue>): void {
for (const [name, value] of Object.entries(params)) {
// Get position for named parameter
const position = this._statement.namedPosition(name);
if (position < 0) {
throw new Error(`Unknown parameter name: ${name}`);
}
this.bindValue(position, value);
}
}
/**
* Bind a single value at a position
*
* @param position - 1-indexed position
* @param value - Value to bind
*/
private bindValue(position: number, value: SQLiteValue): void {
if (value === null || value === undefined) {
this._statement.bindPositionalNull(position);
} else if (typeof value === 'number') {
// Check if integer or float
if (Number.isInteger(value)) {View on GitHub (pinned to bad083fafb)
Solutions
- Make every object key match a named parameter in the SQL text exactly (watch the :, @, $ prefix form on both sides)
- Strip extraneous keys before binding — bind only the parameters the statement actually declares
- Centralize parameter names as constants shared by the SQL template and the bind object so they cannot drift
Example fix
// before
const stmt = conn.prepare('SELECT * FROM users WHERE id = :userId');
stmt.bind({ id: 42 }); // throws: Unknown parameter name: id
// after
const stmt = conn.prepare('SELECT * FROM users WHERE id = :userId');
stmt.bind({ userId: 42 }); Defensive patterns
Strategy: validation
Validate before calling
// Validate keys against the SQL's own parameter names before binding
function namedParamsOf(sql: string): Set<string> {
return new Set(
(sql.match(/[:@$][A-Za-z_][\w$]*/g) ?? []).map((p) => p.replace(/^[:@$]/, ''))
);
}
function pickBindObject(sql: string, obj: Record<string, SQLiteValue>) {
const known = namedParamsOf(sql);
const out: Record<string, SQLiteValue> = {};
for (const [k, v] of Object.entries(obj)) {
if (known.has(k.replace(/^[:@$]/, ''))) out[k] = v;
}
return out; // extraneous keys dropped, typos become 'missing param' which is easier to spot
} Try / catch
try { stmt.bind(params); } catch (e) { if (e instanceof Error && /Unknown parameter name/.test(e.message)) { throw new Error(`${e.message} — SQL expects one of: ${[...namedParamsOf(sql)]}`); } throw e; } Prevention
- Share parameter-name constants between the SQL template and the bind object
- Never pass raw request bodies as bind objects — pick known keys first
- Match the :, @, $ prefix convention consistently between SQL and keys
When it happens
Trigger: `stmt.bind({ id: 1 })` where the SQL is 'SELECT * FROM t WHERE id = :userId' (id vs userId); passing an options object with extraneous keys alongside the real parameters; SQL rewritten to rename or remove a parameter while caller code still passes the old key; prefix conventions mixed (':name' in SQL but '@name' passed, where matching is prefix-sensitive).
Common situations: Passing a row object plus metadata keys (e.g., reusing a request body as bind params); renaming SQL parameters during a refactor; building dynamic WHERE clauses where the parameter set and the object keys drift; copy-pasting SQL from one query to another with different parameter names.
Related errors
- Unsupported parameter type: ${typeof value}
- Statement has been finalized
- The supplied SQL string contains no statements
- database must be connected before execution the function
- Turso native module not loaded
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/3346a989d5ba48c8.
Report an issue: GitHub.