{"record":{"id":"19a6152a11b581f3","repo":"libnyanpasu/clash-nyanpasu","slug":"invalid-theme-color-19a615","errorCode":null,"errorMessage":"Invalid theme color: {}","messagePattern":"Invalid theme color: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/feat.rs","lineNumber":352,"sourceCode":"            Config::clash().data().save_config()?;\n            Ok(rebuilt)\n        }\n        Err(err) => {\n            Config::clash().discard();\n            Err(err)\n        }\n    }\n}\n\n/// 修改verge的配置\n/// 一般都是一个个的修改\npub async fn patch_verge(client: crate::client::NyanpasuClient, patch: IVerge) -> Result<()> {\n    // Validate theme_color if it's being updated\n    if let Some(ref theme_color) = patch.theme_color\n        && !theme_color.is_empty()\n        && !crate::config::nyanpasu::is_hex_color(theme_color)\n    {\n        anyhow::bail!(\"Invalid theme color: {}\", theme_color);\n    }\n\n    Config::verge().draft().patch_config(patch.clone());\n    let tun_mode = patch.enable_tun_mode;\n    let auto_launch = patch.enable_auto_launch;\n    let system_proxy = patch.enable_system_proxy;\n    let proxy_bypass = patch.system_proxy_bypass;\n    let language = patch.language;\n    let log_level = patch.app_log_level;\n    let log_max_files = patch.max_log_files;\n    let enable_tray_selector = patch.clash_tray_selector;\n    let enable_tray_text = patch.enable_tray_text;\n    let tray_menu_mode = patch.tray_menu_mode;\n    let network_statistic_widget = patch.network_statistic_widget;\n    let res = || async move {\n        let service_mode = patch.enable_service_mode;\n        if let Some(service_mode) = service_mode {\n            log::debug!(target: \"app\", \"change service mode to {}\", service_mode);","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/feat.rs#L334-L370","documentation":"patch_verge validates the optional theme_color field before applying an IVerge patch. If theme_color is set, non-empty, and not a strict '#RRGGBB' hex string (7 chars, '#' prefix, ASCII hex digits only — see is_hex_color in backend/tauri/src/config/nyanpasu/mod.rs:10), the patch is rejected with anyhow::bail and nothing is written.","triggerScenarios":"Calling patch_verge (e.g. via the patch_verge_entrypoint Tauri command) with patch.theme_color = Some(value) where value is not exactly 7 characters of the form #RRGGBB: e.g. 'blue', '#fff', '#GGGGGG', 'rgb(255,0,0)', '#ffffff ' (trailing space), or a full-length '#RRGGBBAA' string.","commonSituations":"Frontend color pickers emitting lowercase names or 3-digit hex; a user typing a color manually into a config UI; switching from a theme that stored alpha-extended hex (#RRGGBBAA) or named colors; a migration/import importing an old verge config with non-hex theme_color; locale-sensitive input adding whitespace.","solutions":["Normalize the value to a 7-character '#RRGGBB' hex string (uppercase or lowercase digits both pass) before calling patch_verge","If the color is not a plain hex (named color, rgb(), 8-digit hex), convert it: expand #RGB to #RRGGBB and drop the alpha bytes","Trim whitespace and confirm length is exactly 7 with a leading '#' before sending the patch","If no theme change is intended, send patch with theme_color: None (or omit the field) instead of an empty or placeholder string"],"exampleFix":"// before\nclient.patch_verge(IVerge { theme_color: Some(\"#fff\".into()), ..patch }).await?;\n// after\nlet color = \"#fff\";\nlet normalized = if color.len() == 4 && color.starts_with('#') {\n    format!(\"#{0}{0}{1}{1}{2}{2}\", &color[1..2], &color[2..3], &color[3..4])\n} else { color.to_string() };\nassert!(crate::config::nyanpasu::is_hex_color(&normalized));\nclient.patch_verge(IVerge { theme_color: Some(normalized), ..patch }).await?;","handlingStrategy":"validation","validationCode":"pub fn valid_theme_color(color: &str) -> bool {\n    color.len() == 7 && color.starts_with('#') && color[1..].chars().all(|c| c.is_ascii_hexdigit())\n}\n// call site\nif let Some(c) = &patch.theme_color {\n    if !c.is_empty() && !valid_theme_color(c) { return Err(anyhow!(\"Invalid theme color: {}\", c)); }\n}","typeGuard":"fn as_valid_theme_color(color: &Option<String>) -> Option<&str> {\n    color.as_deref().filter(|c| !c.is_empty() && c.len() == 7 && c.starts_with('#') && c[1..].chars().all(|c| c.is_ascii_hexdigit()))\n}","tryCatchPattern":"match client.patch_verge(patch).await {\n    Err(e) if e.to_string().starts_with(\"Invalid theme color\") => {\n        log::warn(\"theme_color rejected, reverting to default\");\n        client.patch_verge(IVerge { theme_color: None, ..patch }).await?;\n    }\n    other => other?,\n}","preventionTips":["Always emit colors from the UI as #RRGGBB; expand 3-digit hex and strip alpha before patching","Run is_hex_color (or an equivalent regex ^#[0-9a-fA-F]{6}$) at the form/input layer before submitting","Trim and normalize user-entered colors before storing them in IVerge","Omit theme_color (None) rather than sending empty or placeholder strings when no change is intended"],"tags":["validation","config","rust"],"backgroundTag":"invalid-config-value","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}