{"record":{"id":"38b52ff13b6ec322","repo":"risingwavelabs/risingwave","slug":"cannot-get-database-id-of-fragment-fragment-id","errorCode":null,"errorMessage":"cannot get database_id of fragment {fragment_id}","messagePattern":"cannot get database_id of fragment (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/manager/metadata.rs","lineNumber":348,"sourceCode":"        fragment_map: HashMap<FragmentId, T>,\n    ) -> MetaResult<HashMap<DatabaseId, HashMap<FragmentId, T>>> {\n        let fragment_to_database_map: HashMap<_, _> = self\n            .catalog_controller\n            .list_fragment_database_ids(Some(\n                fragment_map\n                    .keys()\n                    .map(|fragment_id| *fragment_id as _)\n                    .collect(),\n            ))\n            .await?\n            .into_iter()\n            .map(|(fragment_id, database_id)| (fragment_id as FragmentId, database_id))\n            .collect();\n        let mut ret: HashMap<_, HashMap<_, _>> = HashMap::new();\n        for (fragment_id, value) in fragment_map {\n            let database_id = *fragment_to_database_map\n                .get(&fragment_id)\n                .ok_or_else(|| anyhow!(\"cannot get database_id of fragment {fragment_id}\"))?;\n            ret.entry(database_id)\n                .or_default()\n                .try_insert(fragment_id, value)\n                .expect(\"non duplicate\");\n        }\n        Ok(ret)\n    }\n\n    pub async fn list_creating_jobs(&self) -> MetaResult<HashSet<JobId>> {\n        Ok(self\n            .catalog_controller\n            .list_creating_jobs(false, None)\n            .await?\n            .into_iter()\n            .map(|(job_id, _, _, _, _)| job_id)\n            .collect())\n    }\n","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/manager/metadata.rs#L330-L366","documentation":"Thrown by `split_fragment_map_by_database` when a fragment id present in the fragment map has no corresponding entry in the `fragment_to_database_map` derived from catalog tables. This is a catalog-consistency check: every streaming fragment must belong to a known database. It surfaces as an anyhow::Error propagated to the caller of the public API.","triggerScenarios":"Calling `split_fragment_map_by_database` with a fragment map containing a fragment_id that is absent from `fragment_to_database_map` — e.g. the fragment was created but its catalog database row was not yet visible, or the two maps were built from different snapshot points.","commonSituations":"Concurrent DDL while a meta-node snapshot is taken; stale or partially-loaded catalog after failover; fragment records left behind by a failed streaming job whose database mapping was cleaned up; bugs in catalog version synchronization between readers.","solutions":["Check catalog consistency: verify the fragment exists in the fragment catalog table together with its database_id for the same snapshot/version.","Rebuild `fragment_to_database_map` and the fragment map from the same catalog snapshot so they cannot diverge.","If stale fragments from failed jobs exist, clean them up (or skip unmapped fragments) before splitting.","Upgrade/repair meta-node state if the catalog is inconsistent after failover or restore."],"exampleFix":"// before: two independently fetched maps may diverge\nlet fragment_to_database_map = build_fragment_to_database_map().await;\nlet fragment_map = list_fragments().await;\n// after: fetch both from one consistent snapshot\nlet snapshot = catalog.snapshot().await;\nlet fragment_to_database_map = build_fragment_to_database_map(&snapshot);\nlet fragment_map = list_fragments(&snapshot);","handlingStrategy":"validation","validationCode":"// ensure every fragment id is mapped before splitting\nlet unmapped: Vec<_> = fragment_map.keys().filter(|id| !fragment_to_database_map.contains_key(*id)).collect();\nif !unmapped.is_empty() { return Err(anyhow!(\"unmapped fragments: {:?}\", unmapped)); }","typeGuard":"fn is_mapped(fragment_id: &FragmentId, map: &HashMap<u32, DatabaseId>) -> bool { map.contains_key(fragment_id) }","tryCatchPattern":"match split_fragment_map_by_database(...).await {\n    Ok(map) => use(map),\n    Err(e) if e.to_string().contains(\"cannot get database_id\") => refresh_catalog_snapshot_and_retry(),\n    Err(e) => return Err(e),\n}","preventionTips":["Always derive the fragment map and the database map from the same catalog snapshot/version","Clean up orphan fragments from failed jobs before reading fragment maps","After meta failover, verify catalog consistency before running catalog-splitting logic"],"tags":["meta","catalog","consistency"],"backgroundTag":"resource-not-found","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}