{"record":{"id":"b1dbd6374720a4f2","repo":"databendlabs/databend","slug":"required-key-not-found-key-reason-reason","errorCode":null,"errorMessage":"required key not found: {key}; reason: {reason}","messagePattern":"required key not found: (.+?); reason: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/process/src/filter_tenant.rs","lineNumber":512,"sourceCode":"        if !unmarked.is_empty() {\n            anyhow::bail!(\n                \"tenant dump filter did not mark all state machine entries; examples: {}\",\n                unmarked.join(\"; \")\n            );\n        }\n\n        Ok(())\n    }\n\n    fn mark_required_key(\n        &mut self,\n        key: &str,\n        decision: Decision,\n        reason: impl Into<String>,\n    ) -> anyhow::Result<bool> {\n        let reason = reason.into();\n        let Some(index) = self.key_to_state.get(key).copied() else {\n            anyhow::bail!(\"required key not found: {key}; reason: {reason}\");\n        };\n\n        self.mark_existing_key(index, key, decision, reason)\n    }\n\n    fn mark_optional_key(\n        &mut self,\n        key: &str,\n        decision: Decision,\n        reason: impl Into<String>,\n    ) -> anyhow::Result<bool> {\n        let Some(index) = self.key_to_state.get(key).copied() else {\n            return Ok(false);\n        };\n\n        self.mark_existing_key(index, key, decision, reason.into())\n    }\n","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/meta/process/src/filter_tenant.rs#L494-L530","documentation":"mark_required_key marks a key whose presence in the dump is considered mandatory for the filter decision (root classification or a required dependency). It looks the key up in key_to_state; if the key is not indexed at all, the tool cannot even record a decision for it, which breaks the 'every line marked' contract, so it bails with the key and the reason that led to the lookup. (mark_optional_key tolerates missing keys; the required variant does not.)","triggerScenarios":"filter_tenant::mark_all calls mark_required_key for every key from classify_root, and drain_mark_queue calls it for required dependency children returned by dependency_keys(key). The bail fires when such a key has no entry in key_to_state — i.e. dependency_keys or classify_root produced a key that was never parsed into an indexed state line.","commonSituations":"Snapshot dumps with dangling references (a record references a child key that is absent or was already consumed), version-skewed dumps where referenced keys changed format, or bugs in dependency_keys generating malformed key strings.","solutions":["Check the key in the error message: confirm whether it actually exists in the snapshot dump file and under what exact spelling.","Verify the dump was produced by the same metasrv version as the tool; regenerate the dump if versions differ.","If the key exists but was not indexed, fix the snapshot parser's key extraction so that key shape is registered in key_to_state.","If the key legitimately may not exist (dangling reference), switch that call site from mark_required_key to mark_optional_key, which returns Ok(false) for missing keys."],"exampleFix":"// before\nself.mark_required_key(&child.key, decision, reason)?;\n// after (child is known to be possibly-absent)\nself.mark_optional_key(&child.key, decision, reason)?;","handlingStrategy":"validation","validationCode":"fn ensure_required_key_present(idx: &HashMap<String, usize>, key: &str, reason: &str) -> anyhow::Result<()> {\n    anyhow::ensure!(\n        idx.contains_key(key),\n        \"required key {key} missing from dump (context: {reason})\"\n    );\n    Ok(())\n}","typeGuard":"fn required_key(idx: &HashMap<String, usize>, key: &str) -> anyhow::Result<usize> {\n    idx.get(key).copied()\n        .ok_or_else(|| anyhow::anyhow!(\"required key not found: {key}\"))\n}","tryCatchPattern":"match filter.mark_required_key(&key, Decision::Keep, \"root record\") {\n    Ok(_) => {}\n    Err(e) if e.to_string().contains(\"required key not found\") => {\n        // dangling reference in the dump; treat as absent and continue\n        eprintln!(\"dangling reference: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use mark_optional_key for keys whose absence is acceptable; reserve mark_required_key for truly mandatory records.","Check the dump for dangling references (keys pointing to missing records) before filtering.","Keep the metasrv version that exports the dump in lockstep with the filter tool.","Add tests that include intentionally dangling references to exercise the missing-key path."],"tags":["rust","meta","missing-key","snapshot"],"backgroundTag":"record-not-found","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}