zed-industries/zed · error
Expected play_sound_when_agent_done to be a boolean or valid
Error message
Expected play_sound_when_agent_done to be a boolean or valid enum value
What it means
The m_2026_03_30 migration converts `agent.play_sound_when_agent_done` from a boolean to the string enum never/when_hidden/always. true→"always", false→"never", and already-valid enum strings pass through; anything else (number, object, array, or an unknown string) bails and stops settings migration.
Source
Thrown at crates/migrator/src/migrations/m_2026_03_30/settings.rs:24
pub fn make_play_sound_when_agent_done_an_enum(value: &mut Value) -> Result<()> {
migrate_settings(value, &mut migrate_one)
}
fn migrate_one(obj: &mut serde_json::Map<String, Value>) -> Result<()> {
let Some(play_sound) = obj
.get_mut("agent")
.and_then(|agent| agent.as_object_mut())
.and_then(|agent| agent.get_mut("play_sound_when_agent_done"))
else {
return Ok(());
};
*play_sound = match play_sound {
Value::Bool(true) => Value::String("always".to_string()),
Value::Bool(false) => Value::String("never".to_string()),
Value::String(s) if s == "never" || s == "when_hidden" || s == "always" => return Ok(()),
_ => {
anyhow::bail!("Expected play_sound_when_agent_done to be a boolean or valid enum value")
}
};
Ok(())
}
View on GitHub (pinned to f4178619ac)
Solutions
- Set the value to one of "never", "when_hidden", or "always"
- Or write a boolean (true/false) and let the migration convert it
- Delete the key to use the default
Example fix
// before
"agent": { "play_sound_when_agent_done": "yes" }
// after
"agent": { "play_sound_when_agent_done": "always" } Defensive patterns
Strategy: validation
Validate before calling
const VALID: [&str; 3] = ["never", "when_hidden", "always"];
fn play_sound_ok(value: &serde_json::Value) -> bool {
value
.pointer("/agent/play_sound_when_agent_done")
.map_or(true, |v| {
v.is_boolean() || v.as_str().map_or(false, |s| VALID.contains(&s))
})
} Type guard
fn is_valid_play_sound_setting(v: &serde_json::Value) -> bool {
v.is_boolean()
|| v.as_str().map_or(false, |s| matches!(s, "never" | "when_hidden" | "always"))
} Try / catch
match migrate(&mut settings) {
Err(e) if e.to_string().contains("play_sound_when_agent_done") => {
// set the key to "never"/"always" or remove it, re-run
}
r => r?,
} Prevention
- Write booleans or the exact enum strings only
- Avoid truthy shorthand like 1 or "yes" in settings.json
- Review agent settings after upgrades; enums replace booleans over time
When it happens
Trigger: settings.json contains "agent": { "play_sound_when_agent_done": 1 } or an unrecognized string like "yes" when Zed runs its startup migrations.
Common situations: Guessing truthy values (1, "yes", "true") for what became a three-way enum; settings synced from older Zed versions through dotfile managers with manual edits.
Related errors
- Expected include_ignored to be a boolean or null
- Expected relative_line_numbers to be a boolean
- agent.tool_permissions should be an object or null when migr
- Cannot list directory because its path matches the user's gl
- Cannot list directory because its path matches the user's gl
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/f48fc97680bd6657.
Report an issue: GitHub.