{"record":{"id":"cb6c7b3a71d4fdfe","repo":"risingwavelabs/risingwave","slug":"job-id-column-not-found-in-backfill-table","errorCode":null,"errorMessage":"`job_id` column not found in backfill table","messagePattern":"`job_id` column not found in backfill table","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/rule/table_function_to_internal_backfill_progress.rs","lineNumber":186,"sourceCode":"\nimpl TableFunctionToInternalBackfillProgressRule {\n    pub fn create() -> BoxedRule {\n        Box::new(TableFunctionToInternalBackfillProgressRule {})\n    }\n}\n\nstruct BackfillInfo {\n    job_id: JobId,\n    fragment_id: FragmentId,\n    table_id: TableId,\n    row_count_column_index: usize,\n    epoch_column_index: Option<usize>,\n}\n\nimpl BackfillInfo {\n    fn new(table: &TableCatalog) -> anyhow::Result<Self> {\n        let Some(job_id) = table.job_id else {\n            bail!(\"`job_id` column not found in backfill table\");\n        };\n        let Some(row_count_column_index) = table\n            .columns\n            .iter()\n            .position(|c| c.name() == StreamTableScan::ROW_COUNT_COLUMN_NAME)\n        else {\n            bail!(\n                \"`{}` column not found in backfill table\",\n                StreamTableScan::ROW_COUNT_COLUMN_NAME\n            );\n        };\n        let epoch_column_index = table\n            .columns\n            .iter()\n            .position(|c| c.name() == StreamTableScan::EPOCH_COLUMN_NAME);\n        let fragment_id = table.fragment_id;\n        let table_id = table.id;\n","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/rule/table_function_to_internal_backfill_progress.rs#L168-L204","documentation":"`BackfillInfo::new` extracts metadata from an internal backfill table catalog. If the table catalog lacks a `job_id`, the constructor bails because backfill progress planning cannot identify the owning background job.","triggerScenarios":"The rule `table_function_to_internal_backfill_progress` converts an internal table-function scan and finds the resolved internal backfill TableCatalog has `job_id == None`.","commonSituations":"Querying internal backfill progress tables/functions against tables created by older RisingWave versions before job_id was recorded, or catalogs whose internal metadata was not populated.","solutions":["Upgrade the cluster/tables so internal backfill tables carry job_id metadata.","Verify you are targeting a real backfill table (created during an ongoing backfill) rather than an unrelated internal table.","Recreate the table/MV so a fresh backfill job registers job_id.","Check the catalog via internal system tables to confirm job metadata exists."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Catch catalog errors when reading internal backfill tables\nmatch BackfillInfo::new(&table) {\n    Ok(info) => /* use info */,\n    Err(e) => eprintln!(\"backfill table lacks job metadata: {e:#}\"),\n}","preventionTips":["Keep cluster and table metadata versions aligned (job_id was added in newer versions)","Only query internal backfill tables for objects that are actively backfilling","Recreate objects if internal metadata predates job_id support"],"tags":["rust","optimizer","backfill","catalog"],"backgroundTag":"missing-required-config-field","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}