risingwavelabs/risingwave · error

` ` column not found in backfill table

Error message

`{}` column not found in backfill table

What it means

`BackfillInfo::new` locates the internal row-count column (`StreamTableScan::ROW_COUNT_COLUMN_NAME`) in the backfill table's schema. If the column is absent, it bails naming the missing column, since progress computation depends on it.

Solutions

  1. Ensure the target is the current internal backfill table with the row-count column (check its schema).
  2. Upgrade to a version where the internal table schema matches what the rule expects.
  3. Recreate the backfilling object to regenerate the internal table.
  4. Use the documented progress-view API instead of the internal table function.
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the internal table schema contains the row-count column before use
-- SELECT * FROM <internal_backfill_table> LIMIT 0; verify column present

Try / catch

match BackfillInfo::new(&table) {
    Ok(info) => /* proceed */,
    Err(e) => eprintln!("internal backfill schema mismatch: {e:#}"),
}

Prevention

When it happens

Trigger: Same rule path as error 1443: the internal backfill TableCatalog's `columns` do not include the row-count column, so `position(...)` returns None.

Common situations: Internal table schema drift between versions, or querying a non-backfill internal table that lacks the synthetic row-count column.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/846e891a075d25c8. Report an issue: GitHub.

Appendix: source

Thrown at src/frontend/src/optimizer/rule/table_function_to_internal_backfill_progress.rs:193

struct BackfillInfo {
    job_id: JobId,
    fragment_id: FragmentId,
    table_id: TableId,
    row_count_column_index: usize,
    epoch_column_index: Option<usize>,
}

impl BackfillInfo {
    fn new(table: &TableCatalog) -> anyhow::Result<Self> {
        let Some(job_id) = table.job_id else {
            bail!("`job_id` column not found in backfill table");
        };
        let Some(row_count_column_index) = table
            .columns
            .iter()
            .position(|c| c.name() == StreamTableScan::ROW_COUNT_COLUMN_NAME)
        else {
            bail!(
                "`{}` column not found in backfill table",
                StreamTableScan::ROW_COUNT_COLUMN_NAME
            );
        };
        let epoch_column_index = table
            .columns
            .iter()
            .position(|c| c.name() == StreamTableScan::EPOCH_COLUMN_NAME);
        let fragment_id = table.fragment_id;
        let table_id = table.id;

        Ok(Self {
            job_id,
            fragment_id,
            table_id,
            row_count_column_index,
            epoch_column_index,
        })

View on GitHub (pinned to 6469eb736d)