{"record":{"id":"0edd29f7b9680e80","repo":"Hmbown/CodeWhale","slug":"failed-to-update-setting-invalid-focus-texture","errorCode":null,"errorMessage":"Failed to update setting: invalid focus texture '{value}'. Expected: off, scrim, or grain.","messagePattern":"Failed to update setting: invalid focus texture '(.+?)'\\. Expected: off, scrim, or grain\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/settings.rs","lineNumber":1254,"sourceCode":"            \"low_motion\" | \"motion\" => {\n                self.low_motion = parse_bool(value)?;\n            }\n            \"fancy_animations\" | \"fancy\" | \"animations\" => {\n                self.fancy_animations = parse_bool(value)?;\n            }\n            \"ocean_treatment\" | \"treatment\" | \"background_treatment\" => {\n                let normalized = value.trim().to_ascii_lowercase();\n                if !matches!(normalized.as_str(), \"ombre\" | \"flat\") {\n                    anyhow::bail!(\n                        \"Failed to update setting: invalid ocean treatment '{value}'. Expected: ombre or flat.\"\n                    );\n                }\n                self.ocean_treatment = normalized;\n            }\n            \"focus_texture\" | \"texture\" => {\n                let normalized = value.trim().to_ascii_lowercase();\n                if !matches!(normalized.as_str(), \"off\" | \"scrim\" | \"grain\") {\n                    anyhow::bail!(\n                        \"Failed to update setting: invalid focus texture '{value}'. Expected: off, scrim, or grain.\"\n                    );\n                }\n                self.focus_texture = normalized;\n            }\n            \"work_surface_placement\" | \"work_surface\" | \"work_rail\" => {\n                let normalized = value.trim().to_ascii_lowercase();\n                if !matches!(normalized.as_str(), \"top\" | \"left\" | \"right\" | \"off\") {\n                    anyhow::bail!(\n                        \"Failed to update setting: invalid work surface placement '{value}'. Expected: top, left, right, or off.\"\n                    );\n                }\n                self.work_surface_placement = normalized;\n            }\n            \"rail_panel\" | \"rail\" => {\n                let normalized = value.trim().to_ascii_lowercase();\n                if !matches!(\n                    normalized.as_str(),","sourceCodeStart":1236,"sourceCodeEnd":1272,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/settings.rs#L1236-L1272","documentation":"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.","triggerScenarios":"/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","commonSituations":"Users typing intuitive-but-wrong names (blur, noise, none); config portability across versions; frontends not restricting the input vocabulary.","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"],"exampleFix":"// before\nsettings.update(\"texture\", \"blur\")?; // invalid\n\n// after\nsettings.update(\"texture\", \"scrim\")?; // or \"off\" / \"grain\"","handlingStrategy":"type-guard","validationCode":"let v = value.trim().to_ascii_lowercase();\nif !matches!(v.as_str(), \"off\" | \"scrim\" | \"grain\") {\n    return Err(anyhow::anyhow!(\"unsupported focus texture\"));\n}\nsettings.update(\"focus_texture\", &v)?;","typeGuard":"fn is_valid_focus_texture(value: &str) -> bool {\n    matches!(value.trim().to_ascii_lowercase().as_str(), \"off\" | \"scrim\" | \"grain\")\n}","tryCatchPattern":"match settings.update(\"focus_texture\", value) {\n    Ok(()) => {}\n    Err(err) if err.to_string().contains(\"invalid focus texture\") => {\n        settings.update(\"focus_texture\", \"off\")?; // safe default\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["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"],"tags":["rust","settings","validation","tui","configuration"],"backgroundTag":"invalid-settings-value","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}