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
- Register settings through register_setting / T::register(cx) so the global value is computed from merged settings content at registration time.
- For reads that may hit unpopulated state, use try_get::<T>() which returns None instead of panicking.
- If you build store state manually in tests, always follow with set_global_value/refresh before reading.
- 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
- Always create setting entries via register_setting so the global value is set from merged content immediately.
- Do not hand-construct SettingValue state in tests; use the store APIs.
- Use try_get where population timing is uncertain.
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
- unregistered setting type {}
- row out of range
- invalid display row {}
- blocking sender returned without value
- anchor's path was never added to multibuffer
AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20).
Data as JSON: /api/errors/62ff5a6aa835a5dd.
Report an issue: GitHub.