drizzle-team/drizzle-orm · error · Error
No value for placeholder "${p.value.name}" was provided
Error message
No value for placeholder "${p.value.name}" was provided What it means
Thrown by fillPlaceholders() (sql.ts:624) for the same reason as 144, but the placeholder is wrapped inside a Param object that carries a custom column encoder (e.g. a typed placeholder bound to a column). Drizzle still needs the named value from the values map and throws when it is missing.
Source
Thrown at drizzle-orm/src/sql/sql.ts:624
/** @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>;
const IsDrizzleView = Symbol.for('drizzle:IsDrizzleView');
export abstract class View<
TName extends string = string,
TExisting extends boolean = boolean,
TSelection extends ColumnsSelection = ColumnsSelection,
> implements SQLWrapper {View on GitHub (pinned to b7862528fd)
Solutions
- Supply every placeholder name in the placeholderValues argument at execute time.
- Log the names of placeholders embedded in the query before executing to catch missing keys.
- Centralise placeholder-name constants to avoid drift between build and call sites.
Example fix
// before
const q = db.select().from(users)
.where(sql`${users.id} = ${sql.placeholder('uid')}`).prepare();
await q.all({ wrong: 1 }); // throws
// after
await q.all({ uid: 1 }); Defensive patterns
Strategy: validation
Validate before calling
// same as 144: ensure every placeholder name (including those wrapped in Param/encoder)
// is present in the values object before calling execute/all/run.
function assertPlaceholders(names: string[], values: Record<string, unknown>) {
const missing = names.filter((n) => !(n in values));
if (missing.length) throw new Error('Missing placeholder values: ' + missing.join(', '));
} Type guard
const hasAllKeys = (obj, keys: string[]) => keys.every((k) => k in obj);
Prevention
- Keep placeholder-name constants in one place for both build and execute.
- When wrapping placeholders in typed Param helpers, document the required value keys.
- Unit-test prepared queries against a complete values fixture.
When it happens
Trigger: Using a column-bound placeholder (e.g. new Param(new Placeholder('x'), column)) — typically produced by passing a placeholder through a typed column context — then executing without supplying that name in placeholderValues.
Common situations: Building typed parameterised fragments with sql.placeholder inside typed column expressions; refactoring encoders; placeholders created indirectly through helper functions that wrap them in Param.
Related errors
- No value for placeholder "${p.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/7576a56978dee261.json.
Report an issue: GitHub.