zed-industries/zed · error

Expected include_ignored to be a boolean or null

Error message

Expected include_ignored to be a boolean or null

What it means

Same m_2025_10_17 migration, one level deeper: after `file_finder` is confirmed to be an object, `include_ignored` is remapped (true→"all", false→"indexed", null→"smart", existing all/indexed/smart strings pass through). Any other value — a number, an array, or an unrecognized string like "everything" — hits the catch-all arm and bails.

Source

Thrown at crates/migrator/src/migrations/m_2025_10_17/settings.rs:27

fn migrate_one(obj: &mut serde_json::Map<String, Value>) -> Result<()> {
    let Some(file_finder) = obj.get_mut("file_finder") else {
        return Ok(());
    };

    let Some(file_finder_obj) = file_finder.as_object_mut() else {
        anyhow::bail!("Expected file_finder to be an object");
    };

    let Some(include_ignored) = file_finder_obj.get_mut("include_ignored") else {
        return Ok(());
    };
    *include_ignored = match include_ignored {
        Value::Bool(true) => Value::String("all".to_string()),
        Value::Bool(false) => Value::String("indexed".to_string()),
        Value::Null => Value::String("smart".to_string()),
        Value::String(s) if s == "all" || s == "indexed" || s == "smart" => return Ok(()),
        _ => anyhow::bail!("Expected include_ignored to be a boolean or null"),
    };
    Ok(())
}

View on GitHub (pinned to f4178619ac)

Solutions

  1. Set include_ignored to one of the accepted strings: "all", "indexed", or "smart"
  2. Or restore the boolean form (true/false) and let the migration convert it on next start
  3. Remove the key to accept the default ("smart")

Example fix

// before
"file_finder": { "include_ignored": "everything" }

// after
"file_finder": { "include_ignored": "all" }
Defensive patterns

Strategy: validation

Validate before calling

const VALID: [&str; 3] = ["all", "indexed", "smart"];
fn include_ignored_ok(value: &serde_json::Value) -> bool {
    value
        .pointer("/file_finder/include_ignored")
        .map_or(true, |v| {
            v.is_boolean() || v.is_null()
                || v.as_str().map_or(false, |s| VALID.contains(&s))
        })
}

Type guard

fn is_valid_include_ignored(v: &serde_json::Value) -> bool {
    matches!(v, serde_json::Value::Bool(_))
        || v.is_null()
        || v.as_str().map_or(false, |s| matches!(s, "all" | "indexed" | "smart"))
}

Try / catch

match migrate_one(&mut obj) {
    Err(e) if e.to_string().contains("include_ignored") => {
        obj.get_mut("file_finder").unwrap().as_object_mut().unwrap().remove("include_ignored");
    }
    r => r?,
}

Prevention

When it happens

Trigger: settings.json has "file_finder": { "include_ignored": 1 } or "include_ignored": "everything"; the key being absent is fine, only present-but-unrecognized values fail.

Common situations: Typos in the enum value; users guessing a string value before the schema was widely documented; scripts writing raw numbers into the field.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/6f3d062f7d4a0a63. Report an issue: GitHub.