{"record":{"id":"1ab97b2061285d47","repo":"a-b-street/abstreet","slug":"missing","errorCode":null,"errorMessage":"missing {}","messagePattern":"missing (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"abstutil/src/collections.rs","lineNumber":294,"sourceCode":"/// Convenience functions around a string->string map\n#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]\npub struct Tags(BTreeMap<String, String>);\n\nimpl Tags {\n    pub fn new(map: BTreeMap<String, String>) -> Tags {\n        Tags(map)\n    }\n\n    pub fn empty() -> Tags {\n        Tags(BTreeMap::new())\n    }\n\n    pub fn get(&self, k: &str) -> Option<&String> {\n        self.0.get(k)\n    }\n\n    pub fn get_result(&self, k: &str) -> Result<&String> {\n        self.0.get(k).ok_or_else(|| anyhow!(\"missing {}\", k))\n    }\n\n    pub fn contains_key(&self, k: &str) -> bool {\n        self.0.contains_key(k)\n    }\n\n    pub fn has_any(&self, keys: Vec<&str>) -> bool {\n        keys.into_iter().any(|key| self.contains_key(key))\n    }\n\n    pub fn is(&self, k: &str, v: &str) -> bool {\n        self.0.get(k) == Some(&v.to_string())\n    }\n\n    pub fn is_any(&self, k: &str, values: Vec<&str>) -> bool {\n        if let Some(v) = self.0.get(k) {\n            values.contains(&v.as_ref())\n        } else {","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/abstutil/src/collections.rs#L276-L312","documentation":"get_result on an imported-JSON-style String map (abstutil::collections) looks up a key and, if absent, returns anyhow!(\"missing {}\"). It is the fallible counterpart to get(), used by callers that treat a key's presence as mandatory.","triggerScenarios":"Calling get_result(key) when the map loaded from JSON (e.g. a scenario or config file) does not contain that key — the key was renamed, removed, or never present in the file.","commonSituations":"Schema drift between code and persisted JSON files; typos in keys; older data files missing newly required fields; hand-edited input files.","solutions":["Check the key exists with contains_key or get before calling get_result, or handle the Err branch","Regenerate/update the JSON input file so it includes the expected key","Use get() with a default if the key is truly optional","Match the file schema version expected by the current code"],"exampleFix":"// before\nlet v = map.get_result(\"color\")?;\n// after\nlet v = map.get(\"color\")\n    .with_context(|| format(\"missing optional key 'color', using default\"))\n    .unwrap_or(&\"black\".to_string());","handlingStrategy":"validation","validationCode":"if !map.contains_key(\"color\") {\n    return Err(anyhow!(\"input JSON is missing key 'color'\"));\n}","typeGuard":null,"tryCatchPattern":"match map.get_result(\"color\") {\n    Ok(v) => use(v),\n    Err(e) => handle_missing_key(e),\n}","preventionTips":["Validate required keys right after loading JSON files","Keep input file schemas in sync with code; version your data files","Prefer get() with defaults for optional keys"],"tags":["json","lookup","missing-key","config"],"backgroundTag":"missing-required-argument","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}