Hmbown/CodeWhale · error · anyhow::Error
Failed to update setting: invalid focus texture '{value}'. E
Error message
Failed to update setting: invalid focus texture '{value}'. Expected: off, scrim, or grain. What it means
SettingsStore.update validates focus_texture and only accepts off, scrim, or grain (after trim + lowercase) (crates/tui/src/settings.rs:1254). Any other value is rejected before mutation, so the previous setting survives intact.
Source
Thrown at crates/tui/src/settings.rs:1254
"low_motion" | "motion" => {
self.low_motion = parse_bool(value)?;
}
"fancy_animations" | "fancy" | "animations" => {
self.fancy_animations = parse_bool(value)?;
}
"ocean_treatment" | "treatment" | "background_treatment" => {
let normalized = value.trim().to_ascii_lowercase();
if !matches!(normalized.as_str(), "ombre" | "flat") {
anyhow::bail!(
"Failed to update setting: invalid ocean treatment '{value}'. Expected: ombre or flat."
);
}
self.ocean_treatment = normalized;
}
"focus_texture" | "texture" => {
let normalized = value.trim().to_ascii_lowercase();
if !matches!(normalized.as_str(), "off" | "scrim" | "grain") {
anyhow::bail!(
"Failed to update setting: invalid focus texture '{value}'. Expected: off, scrim, or grain."
);
}
self.focus_texture = normalized;
}
"work_surface_placement" | "work_surface" | "work_rail" => {
let normalized = value.trim().to_ascii_lowercase();
if !matches!(normalized.as_str(), "top" | "left" | "right" | "off") {
anyhow::bail!(
"Failed to update setting: invalid work surface placement '{value}'. Expected: top, left, right, or off."
);
}
self.work_surface_placement = normalized;
}
"rail_panel" | "rail" => {
let normalized = value.trim().to_ascii_lowercase();
if !matches!(
normalized.as_str(),View on GitHub (pinned to 0c42157ee5)
Solutions
- Use one of off, scrim, or grain (casing is normalized)
- Restrict UI inputs to a dropdown of allowed values
- Validate persisted settings on load and reset invalid entries to the default
- Re-check allowed values after upgrading the TUI
Example fix
// before
settings.update("texture", "blur")?; // invalid
// after
settings.update("texture", "scrim")?; // or "off" / "grain" Defensive patterns
Strategy: type-guard
Validate before calling
let v = value.trim().to_ascii_lowercase();
if !matches!(v.as_str(), "off" | "scrim" | "grain") {
return Err(anyhow::anyhow!("unsupported focus texture"));
}
settings.update("focus_texture", &v)?; Type guard
fn is_valid_focus_texture(value: &str) -> bool {
matches!(value.trim().to_ascii_lowercase().as_str(), "off" | "scrim" | "grain")
} Try / catch
match settings.update("focus_texture", value) {
Ok(()) => {}
Err(err) if err.to_string().contains("invalid focus texture") => {
settings.update("focus_texture", "off")?; // safe default
}
Err(err) => return Err(err),
} Prevention
- Offer a dropdown with off/scrim/grain instead of free text
- Never guess plausible values (blur, noise, none) — check the allowed set
- Sanitize settings files on load; reset unknown values to defaults
- Map legacy texture names during config migration rather than passing them through
When it happens
Trigger: /set texture blur or settings.update("focus_texture", "none") with an unsupported value; settings files written for an older build whose texture names changed; scripts feeding free-text input straight into update
Common situations: Users typing intuitive-but-wrong names (blur, noise, none); config portability across versions; frontends not restricting the input vocabulary.
Related errors
- Failed to update setting: invalid ocean treatment '{value}'.
- Failed to update setting: invalid work surface placement '{v
- Failed to parse boolean '{value}': expected on/off, true/fal
- Invalid {key} '{value}': expected {min}-{max}
- Failed to update setting: invalid {key} '{value}'. Expected
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/0edd29f7b9680e80.
Report an issue: GitHub.