zed-industries/zed · warning

{error}

Error message

{error}

What it means

fallible_options deserialization parses settings values leniently: recover_deserialization_error collects each deserialization problem reported by serde into a thread-local ERRORS list as anyhow errors, so parsing can continue and all issues be reported at once. This entry is the error created per offending value — meaning one or more settings fields in the user's settings file had values that could not be deserialized into the expected option types.

Solutions

  1. Read the collected error messages — each names the offending settings key and expected type — and correct those values in settings.json.
  2. Check for schema changes after upgrading: compare the settings keys against the current defaults/documentation for the installed version.
  3. Remove the offending key entirely to fall back to the default value if you don't need it.
  4. Validate the settings JSON types with a JSON schema/linter before saving.

Example fix

// before (settings.json)
{ "buffer_font_size": "14" }
// after
{ "buffer_font_size": 14 }
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate the settings value types before deserialization
fn check_setting(key: &str, value: &serde_json::Value, expected: &str) -> bool {
    let ok = match expected {
        "bool" => value.is_boolean(),
        "number" => value.is_number(),
        "string" => value.is_string(),
        _ => true,
    };
    if !ok { eprintln!("{key}: expected {expected}, got {value}"); }
    ok
}

Try / catch

match SettingsContent::deserialize(&value) {
    Ok(content) => apply(content),
    Err(e) => {
        for err in collected_errors() { // fallible_options collects each bad field
            eprintln!("settings issue: {err:#}");
        }
        apply_defaults();
    }
}

Prevention

When it happens

Trigger: Deserializing a settings file (via deserialize → recover_deserialization_error) where a field expected as a fallible option (e.g. bool, number, enum) holds an incompatible value; serde's recover callback is invoked with the display of each failing field's error and it is pushed into the collected errors.

Common situations: Hand-edited settings.json with a mistyped value ("true" as string instead of boolean, wrong enum variant, nested object where scalar expected); settings written by an older Zed version whose schema has changed; copy-pasted config from documentation of a different version.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19). Data as JSON: /api/errors/8167deb75708e00d. Report an issue: GitHub.

Appendix: source

Thrown at crates/settings_content/src/fallible_options.rs:161

{
    match object.remove(key) {
        None => Ok(T::default()),
        Some(value) => T::deserialize(&value),
    }
}

pub(crate) fn section<T>(rest: &serde_json::Value) -> Result<T, serde_json::Error>
where
    T: serde::de::DeserializeOwned,
{
    T::deserialize(rest)
}

#[inline(never)]
fn recover_deserialization_error(recover: &mut dyn FnMut(&mut dyn FnMut(&dyn Display))) {
    ERRORS.with_borrow_mut(|errors| {
        if let Some(errors) = errors {
            recover(&mut |error| errors.push(anyhow::anyhow!("{error}")));
        }
    });
}

#[cfg(test)]
mod tests {
    use serde::Deserialize;
    use settings_macros::with_fallible_options;

    use crate::ParseStatus;

    #[with_fallible_options]
    #[derive(Deserialize, Debug, PartialEq)]
    struct Foo {
        foo: Option<String>,
        bar: Option<usize>,
        baz: Option<bool>,
    }

View on GitHub (pinned to 916fc2b8cb)