drizzle-team/drizzle-orm · error · Error
No value for placeholder "${p.name}" was provided
Error message
No value for placeholder "${p.name}" was provided What it means
Thrown by fillPlaceholders() (sql.ts:616) when a Placeholder created via sql.placeholder('name') appears in the built parameter list but the supplied values record does not contain a key matching that name. fillPlaceholders is called when you execute a prepared query with placeholderValues. This form covers a bare Placeholder object.
Source
Thrown at drizzle-orm/src/sql/sql.ts:616
declare protected: TValue;
constructor(readonly name: TName) {}
getSQL(): SQL {
return new SQL([this]);
}
}
/** @deprecated Use `sql.placeholder` instead. */
export function placeholder<TName extends string>(name: TName): Placeholder<TName> {
return new Placeholder(name);
}
export function fillPlaceholders(params: unknown[], values: Record<string, unknown>): unknown[] {
return params.map((p) => {
if (is(p, Placeholder)) {
if (!(p.name in values)) {
throw new Error(`No value for placeholder "${p.name}" was provided`);
}
return values[p.name];
}
if (is(p, Param) && is(p.value, Placeholder)) {
if (!(p.value.name in values)) {
throw new Error(`No value for placeholder "${p.value.name}" was provided`);
}
return p.encoder.mapToDriverValue(values[p.value.name]);
}
return p;
});
}
export type ColumnsSelection = Record<string, unknown>;View on GitHub (pinned to b7862528fd)
Solutions
- Pass a values object that contains every placeholder name used in the query.
- Cross-check placeholder names against the values keys before executing.
- Default missing optional placeholders to null explicitly rather than omitting them.
Example fix
// before
const q = db.select().from(users).where(sql`${users.id} = ${sql.placeholder('uid')}`).prepare();
await q.all({}); // throws: No value for placeholder "uid"
// after
await q.all({ uid: 42 }); Defensive patterns
Strategy: validation
Validate before calling
function fillAllPlaceholders(query, values) {
// collect placeholder names actually used
const needed = new Set(query.toSQL().paramNames ?? []);
const missing = [...needed].filter((n) => !(n in values));
if (missing.length) throw new Error('Missing placeholders: ' + missing.join(', '));
return query.all(values);
} Type guard
const hasAllKeys = (obj, keys: string[]) => keys.every((k) => k in obj && obj[k] !== undefined);
Prevention
- Define placeholder names as constants and reuse them at build and call sites.
- Audit prepared queries after renaming any placeholder.
- Default optional placeholders to null instead of omitting them.
When it happens
Trigger: Building a query with sql.placeholder('userId') then running .all({}) or .all({ otherKey: 1 }) — i.e. omitting the 'userId' key. Also when a placeholder name is misspelled or renamed between build and execute.
Common situations: Prepared queries reused across requests where a field was optional and left out; refactoring a placeholder name without updating every call site; spreading a partial object into placeholderValues.
Related errors
- No value for placeholder "${p.value.name}" was provided
- Unknown type for ${value}
- Method not implemented.
- Method not implemented.
- Unexpected param value: ${chunk}
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/dc30e137658de258.json.
Report an issue: GitHub.