a-b-street/abstreet · error · anyhow::Error

missing

Error message

missing {}

What it means

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.

Solutions

  1. Check the key exists with contains_key or get before calling get_result, or handle the Err branch
  2. Regenerate/update the JSON input file so it includes the expected key
  3. Use get() with a default if the key is truly optional
  4. Match the file schema version expected by the current code

Example fix

// before
let v = map.get_result("color")?;
// after
let v = map.get("color")
    .with_context(|| format("missing optional key 'color', using default"))
    .unwrap_or(&"black".to_string());
Defensive patterns

Strategy: validation

Validate before calling

if !map.contains_key("color") {
    return Err(anyhow!("input JSON is missing key 'color'"));
}

Try / catch

match map.get_result("color") {
    Ok(v) => use(v),
    Err(e) => handle_missing_key(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: Schema drift between code and persisted JSON files; typos in keys; older data files missing newly required fields; hand-edited input files.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/1ab97b2061285d47. Report an issue: GitHub.

Appendix: source

Thrown at abstutil/src/collections.rs:294

/// Convenience functions around a string->string map
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Tags(BTreeMap<String, String>);

impl Tags {
    pub fn new(map: BTreeMap<String, String>) -> Tags {
        Tags(map)
    }

    pub fn empty() -> Tags {
        Tags(BTreeMap::new())
    }

    pub fn get(&self, k: &str) -> Option<&String> {
        self.0.get(k)
    }

    pub fn get_result(&self, k: &str) -> Result<&String> {
        self.0.get(k).ok_or_else(|| anyhow!("missing {}", k))
    }

    pub fn contains_key(&self, k: &str) -> bool {
        self.0.contains_key(k)
    }

    pub fn has_any(&self, keys: Vec<&str>) -> bool {
        keys.into_iter().any(|key| self.contains_key(key))
    }

    pub fn is(&self, k: &str, v: &str) -> bool {
        self.0.get(k) == Some(&v.to_string())
    }

    pub fn is_any(&self, k: &str, values: Vec<&str>) -> bool {
        if let Some(v) = self.0.get(k) {
            values.contains(&v.as_ref())
        } else {

View on GitHub (pinned to 0964f29315)