windmill-labs/windmill · error
26000
26000
Error message
prepared statement ${formatProtocolName(bind.statementName, "statement")} does not exist What it means
In `wmill datatable serve`, a Bind (B) message referenced a statement name that is not present in the connection's `preparedStatements` map, so `handleBindMessage` throws SQLSTATE `26000` (invalid_sql_statement_name). Per the Postgres protocol, a Bind must target a statement created earlier by a Parse on the same connection.
Source
Thrown at cli/src/commands/datatable/serve.ts:441
preparedStatements.set(parse.statementName, {
query: parse.query,
parameterTypeOids: parse.parameterTypeOids,
});
if (parse.statementName === "") {
portals.delete("");
}
return buildParseComplete();
}
function handleBindMessage(
data: Uint8Array,
preparedStatements: Map<string, PreparedStatementState>,
portals: Map<string, PortalState>,
): Uint8Array {
const bind = readBindMessage(data);
const statement = preparedStatements.get(bind.statementName);
if (!statement) {
throw createPgProtocolError(
`prepared statement ${formatProtocolName(bind.statementName, "statement")} does not exist`,
"26000",
);
}
for (let i = 0; i < bind.parameters.length; i += 1) {
if (bind.parameters[i] !== null && resolveParameterFormatCode(bind.parameterFormatCodes, i) !== 0) {
throw createPgProtocolError(
"binary parameter formats are not supported by 'wmill datatable serve'",
"0A000",
);
}
}
if (bind.resultFormatCodes.some((code) => code !== 0)) {
throw createPgProtocolError(
"binary result formats are not supported by 'wmill datatable serve'",
"0A000",
);
}View on GitHub (pinned to e474e8803c)
Solutions
- Reconnect or reset the connection so the driver's prepared-statement cache and the server state resynchronize (the driver will re-Parse on a fresh session).
- Disable prepared statements in the client driver if supported (e.g. `prepared_statements=false` in the Postgres DSN, or `preferPreparedStatements: false`) so Binds always reference the unnamed statement.
- Upgrade `wmill` / the datatable server — a bug where statements were dropped prematurely would be fixed in a newer release.
- In application code, catch SQLSTATE 26000 and retry the query after re-preparing, the standard Postgres recovery for invalid_sql_statement_name.
Example fix
// before postgres://user:pw@host/db // pool reuses cached statement names across connections // after postgres://user:pw@host/db?prepared_statements=false
Defensive patterns
Strategy: retry
Try / catch
async function safeQuery(client, sql, params) {
try {
return await client.query(sql, params);
} catch (err) {
if (err.code === '26000') {
return await client.query({ text: sql, values: params, name: undefined }); // re-issue unnamed
}
throw err;
}
} Prevention
- Catch SQLSTATE 26000 and re-prepare/retry, the standard Postgres recovery.
- Disable client-side prepared statements when connecting through pooling layers or emulators.
- Avoid reusing prepared statement names across pooled/recycled connections.
- After any server error, assume server-side statement state is gone and re-Parse before Bind.
When it happens
Trigger: The client sends Bind for a named statement that was never Parsed, was already closed via a Close (C) message, or belonged to a different connection/session; also happens after a server error discarded prepared statements while the driver's local cache still thinks they exist.
Common situations: Connection pooling/multiplexing where the driver reuses a statement name across recycled connections; a prior error mid-transaction cleared server-side state but the client kept its prepared-statement cache; driver retry logic replaying Bind without re-Parsing after a disconnect.
Related errors
- 0A000
- Datatable '${dtName}' already exists in this workspace
- Workspace already has datatable(s): ${existing.map((d) => d.
- Could not fetch datatable schemas: ${errorMessage}
- Failed to run new datatable migrations: ${e?.body ?? e?.mess
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/013086162ee2e556.
Report an issue: GitHub.