windmill-labs/windmill · error
Unexpected NULL `schema_name` in publication entry (pubname:
Error message
Unexpected NULL `schema_name` in publication entry (pubname: `{}`). This should never happen unless PostgreSQL internals are corrupted. What it means
get_tracked_relations reads publication relation rows from PostgreSQL (pg_publication_tables-style query). The schema_name column is nullable in the row type, but a NULL here would mean corrupt PostgreSQL catalog internals, so the code fails loudly with this error instead of proceeding.
Source
Thrown at backend/windmill-trigger-postgres/src/handler.rs:934
pubname = $1;
"#
};
let rows = pg_connection
.query(query, &[&publication_name])
.await
.map_err(to_anyhow)?;
let mut table_to_track: HashMap<String, Relations> = HashMap::new();
for row in rows {
let schema_name: Option<String> = row.get("schema_name");
let table_name: Option<String> = row.get("table_name");
let columns: Option<Vec<String>> = row.get("columns");
let where_clause: Option<String> = row.get("where_clause");
let schema_name = schema_name.ok_or_else::<Error, _>(|| {
anyhow::anyhow!(
"Unexpected NULL `schema_name` in publication entry (pubname: `{}`). This should never happen unless PostgreSQL internals are corrupted.",
publication_name,
)
.into()
})?;
let table_name = table_name.ok_or_else::<Error, _>(|| {
anyhow::anyhow!(
"Unexpected NULL `table_name` for schema `{}` in publication `{}`. This should never happen unless PostgreSQL internals are corrupted.",
schema_name,
publication_name,
)
.into()
})?;
let entry = table_to_track.entry(schema_name.clone());
let table_to_track_item = TableToTrack::new(table_name, where_clause, columns);
View on GitHub (pinned to e474e8803c)
Solutions
- Verify catalog integrity: dump pg_publication_tables on the same DB and inspect the rows
- Check for pg_upgrade/restore issues; reindex system catalogs or restore from a clean backup
- Confirm the connection targets a real PostgreSQL server, not a shim rewriting catalog queries
- Compare your PostgreSQL version against the versions Windmill's postgres trigger supports
- Report to Windmill if a supported Postgres version reproduces it on a healthy database
Defensive patterns
Strategy: try-catch
Validate before calling
-- verify publication catalog integrity before configuring the trigger SELECT pubname, schemaname, tablename FROM pg_publication_tables WHERE pubname = 'my_publication' AND schemaname IS NULL; -- must return zero rows
Try / catch
match get_publication_info(...).await {
Err(e) if e.to_string().contains("Unexpected NULL `schema_name`") => {
anyhow::bail!("Postgres catalog looks corrupted; refusing to sync publication state")
}
other => other,
} Prevention
- Run the trigger against vanilla PostgreSQL of a supported version
- Avoid proxies/shims that rewrite catalog queries between Windmill and Postgres
- Validate pg_publication_tables after any pg_upgrade or restore
- Keep clean backups; treat system-catalog corruption as a stop-everything incident
When it happens
Trigger: Running the publication-info query against a PostgreSQL instance whose catalog returns NULL schema_name for an entry in the given publication — per PostgreSQL this should never occur in a healthy database.
Common situations: A corrupted system catalog after a botched upgrade/restore; querying via a proxy/federated layer that mangles catalog columns; a Postgres version with divergent catalog behavior read with mismatched column aliases.
Related errors
- Unexpected NULL `table_name` for schema `{}` in publication
- could not read the run of job ${id}: ${res.status} ${await r
- error (from getWorkspaceMutationTargetError)
- Failed to create ${triggerConfig.label} "${requestBody.path}
- Unknown CaptureTriggerKind: ${kind}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/0665444668b77b2e.
Report an issue: GitHub.