{"record":{"id":"27e36a1e59eef79b","repo":"risingwavelabs/risingwave","slug":"job-in-database-has-no-state-table-after-rec","errorCode":null,"errorMessage":"job {} in database {} has no state table after recovery","messagePattern":"job (.+?) in database (.+?) has no state table after recovery","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/meta/src/barrier/mod.rs","lineNumber":201,"sourceCode":"                            \"state table {} is not registered to hummock\",\n                            state_table_id\n                        )\n                        .into());\n                    }\n                }\n            }\n            for (job_id, fragments) in database_jobs {\n                let mut committed_epochs =\n                    InflightFragmentInfo::existing_table_ids(fragments.values()).map(|table_id| {\n                        (\n                            table_id,\n                            *state_table_committed_epochs\n                                .get(&table_id)\n                                .expect(\"checked exist\"),\n                        )\n                    });\n                let (first_table, first_epoch) = committed_epochs.next().ok_or_else(|| {\n                    anyhow!(\n                        \"job {} in database {} has no state table after recovery\",\n                        job_id,\n                        database_id\n                    )\n                })?;\n                for (table_id, epoch) in committed_epochs {\n                    if epoch != first_epoch {\n                        return Err(anyhow!(\n                            \"job {} in database {} has tables with different table ids. {}:{}, {}:{}\",\n                            job_id,\n                            database_id,\n                            first_table,\n                            first_epoch,\n                            table_id,\n                            epoch\n                        )\n                        .into());\n                    }","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/barrier/mod.rs#L183-L219","documentation":"validate_database_info collects each job's state tables with their committed epochs and requires at least one entry. If a streaming job ends up with zero state tables after recovery, recovery aborts with this error — a job without any state table cannot be part of a consistent recovery snapshot.","triggerScenarios":"Recovery where a streaming job (job_id in database_id) maps to no state tables with committed epochs — empty fragment state_table_ids, or all of its tables filtered out during validation.","commonSituations":"Corrupted or partially-written job metadata; a job whose tables were all dropped but the job itself remained; recovery logic bugs dropping table entries.","solutions":["Inspect the job's fragments/state tables in metadata; repair or recreate the job so it owns state tables","Drop the zombie job via DROP MATERIALIZED VIEW / DROP SINK if it no longer has data","Retry recovery from an earlier consistent metadata snapshot","File a bug with job_id/database_id; empty-state-table jobs indicate a creation/drop race"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if job.state_tables().next().is_none() {\n    return Err(format!(\"job {} has no state tables\", job_id));\n}","typeGuard":"fn has_state_tables(job: &StreamingJobInfo) -> bool { job.fragments.iter().any(|f| !f.state_table_ids.is_empty()) }","tryCatchPattern":"if e.to_string().contains(\"has no state table after recovery\") {\n    drop_zombie_job(job_id)?; // or restore from an earlier snapshot and retry\n}","preventionTips":["Ensure job drop removes the job record together with its tables","Block creation paths that can produce tables-less streaming jobs","Validate job metadata after recovery with automated checks"],"tags":["rust","meta","recovery","state-table","consistency"],"backgroundTag":"internal-invariant-violation","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"}