linebender/druid · error
{}
Error message
{} What it means
Env::get<V> panics when the requested key is either absent from the environment or present with the wrong Value type; try_get returns Err whose Display message becomes the panic payload. It exists as the infallible convenience accessor for required theme keys, so the library deliberately crashes loudly instead of substituting a default. Widgets calling env.get(KEY) during paint/layout assume the key was set up in theme setup or by an ancestor.
Solutions
- Set the key before first use: env.set(KEY, value) in app startup (AppDelegate / main) or in the parent widget's lifecycle/init hook.
- Switch to env.try_get(KEY) and handle Err (missing/wrong type) with a fallback value instead of panicking.
- Verify the Key's type parameter matches what was stored — set with Key<Color> and read with Key<Color>, not a different variant.
- If the key should have a default, use the-or pattern: env.get(KEY) after env.try_get(...).unwrap_or(default), or add the key to your theme setup function all widgets share.
Example fix
// before
let color = env.get(MY_BG_COLOR); // panics if unset
// after
let color = env.try_get(MY_BG_COLOR)
.unwrap_or(Color::WHITE); Defensive patterns
Strategy: fallback
Validate before calling
// before calling env.get(KEY):
if env.try_get(KEY).is_err() {
env.set(KEY, default_value);
} Prevention
- Register all custom theme keys in a single setup function invoked at app startup.
- Use try_get with unwrap_or(default) for anything not guaranteed by druid's default theme.
- Keep Key<T> declarations and their set() call sites in one module so the type parameter cannot drift.
When it happens
Trigger: A custom widget calls env.get(MY_KEY) but nothing ever inserted the key via env.set / Env::with (e.g. the key isn't part of druid's default theme and the app never sets it). Calling env.get with a Key typed as one Value variant (e.g. Key<Color>) when the stored value is another (e.g. a f64 was set under the same key). Resetting or replacing the Env and dropping a key that descendants still require. Reading a key in paint_raw/resolve before the value has been provided by a parent widget.
Common situations: Custom theme keys referenced by widgets but never defined in the app's main Env setup. Renaming a Key or its type parameter in one place: Key<K> identity includes the type, and a stale setter inserts the wrong type. Copying an example that relied on druid's built-in theme (TEXT_COLOR, BUTTON_DARK, etc.) into code with a custom-built Env that omits them.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Expected selector " " but the command was " ".
- TabsPolicy::Build called on a policy that does not support…
- commands should be dispatched via dispatch_cmd
- command must carry a ContextMenu .
- Unwrap named called on unnamed FieldIdent
AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10).
Data as JSON: /api/errors/cb6fa1110463fd6d.
Report an issue: GitHub.
Appendix: source
Thrown at druid/src/env.rs:230
/// }
/// ```
///
/// [`WidgetExt::debug_widget`]: crate::WidgetExt::debug_widget
pub const DEBUG_WIDGET: Key<bool> = Key::new("org.linebender.druid.built-in.debug-widget");
/// Gets a value from the environment, expecting it to be present.
///
/// Note that the return value is a reference for "expensive" types such
/// as strings, but an ordinary value for "cheap" types such as numbers
/// and colors.
///
/// # Panics
///
/// Panics if the key is not found, or if it is present with the wrong type.
pub fn get<V: ValueType>(&self, key: impl Borrow<Key<V>>) -> V {
match self.try_get(key) {
Ok(value) => value,
Err(err) => panic!("{}", err),
}
}
/// Tries to get a value from the environment.
///
/// If the value is not found, the raw key is returned as the error.
///
/// # Panics
///
/// Panics if the value for the key is found, but has the wrong type.
pub fn try_get<V: ValueType>(&self, key: impl Borrow<Key<V>>) -> Result<V, MissingKeyError> {
self.0
.map
.get(key.borrow().key)
.map(|value| value.to_inner_unchecked())
.ok_or(MissingKeyError {
key: key.borrow().key.into(),
})View on GitHub (pinned to 0f8b1195e4)