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
- Set include_ignored to one of the accepted strings: "all", "indexed", or "smart"
- Or restore the boolean form (true/false) and let the migration convert it on next start
- 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
- Spell the enum exactly: all / indexed / smart
- Treat booleans and null as the only legacy forms; never numbers
- After settings-sync tools run, spot-check enum keys for corruption
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
- Expected file_finder to be an object
- Expected relative_line_numbers to be a boolean
- Expected play_sound_when_agent_done to be a boolean or valid
- The `code_action` is in an invalid state and cannot be migra
- agent.tool_permissions should be an object or null when migr
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/6f3d062f7d4a0a63.
Report an issue: GitHub.