zed-industries/zed · error

no default value for setting {}

Error message

no default value for setting {}

What it means

Each registered setting keeps its merged global value; value_for_path (crates/settings/src/settings_store.rs:1629) returns a matching local override or unwraps the global value, panicking when it is None. Registration normally sets the global value immediately (register_setting_internal), so in practice this panic means a SettingValue entry exists without its global value ever having been applied — an internal invariant break or a hand-built store in tests rather than a normal user flow.

Source

Thrown at crates/settings/src/settings_store.rs:1629

    }
}
impl std::error::Error for InvalidSettingsError {}

impl Debug for SettingsStore {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("SettingsStore")
            .field(
                "types",
                &self
                    .setting_values
                    .values()
                    .map(|value| value.setting_type_name())
                    .collect::<Vec<_>>(),
            )
            .field("default_settings", &self.default_settings)
            .field("user_settings", &self.user_settings)
            .field("local_settings", &self.local_settings)
            .finish_non_exhaustive()
    }
}

impl<T: Settings> AnySettingValue for SettingValue<T> {
    fn from_settings(&self, s: &SettingsContent) -> Box<dyn Any> {
        Box::new(T::from_settings(s)) as _
    }

    fn setting_type_name(&self) -> &'static str {
        type_name::<T>()
    }

    fn all_local_values(&self) -> Vec<(WorktreeId, Arc<RelPath>, &dyn Any)> {
        self.local_values
            .iter()
            .map(|(id, path, value)| (*id, path.clone(), value as _))
            .collect()
    }

View on GitHub (pinned to 5a9b9558db)

Solutions

  1. Register settings through register_setting / T::register(cx) so the global value is computed from merged settings content at registration time.
  2. For reads that may hit unpopulated state, use try_get::<T>() which returns None instead of panicking.
  3. If you build store state manually in tests, always follow with set_global_value/refresh before reading.
  4. Check for code paths that reset or rebuild setting_values without re-applying defaults.

Example fix

// before: hand-built entry without a global value
store.get::<MySettings>(None); // panics: no default value for setting

// after: register through the normal path
store.register_setting::<MySettings>();
store.get::<MySettings>(None);
Defensive patterns

Strategy: validation

Validate before calling

// prefer the non-panicking read when entry state is uncertain
if let Some(value) = store.try_get::<MySettings>(None) {
    // use value
} else {
    // register/refresh before reading
}

Prevention

When it happens

Trigger: Calling get::<T> on a store whose entry for T was created but never received a global value: constructing SettingValue state directly in tests, or reading between entry creation and the set_global_value call in register_setting_internal (crates/settings/src/settings_store.rs:426-436). The doc on get() states it panics when 'there is no value for this setting'.

Common situations: Test helpers that poke the store's internals instead of going through register_setting; forks or refactor branches that construct SettingValue manually; nothing in the normal app flow.

Related errors


AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20). Data as JSON: /api/errors/62ff5a6aa835a5dd. Report an issue: GitHub.