{"record":{"id":"cc3930d5948829ff","repo":"zed-industries/zed","slug":"button-layout-string-contains-no-valid-button","errorCode":null,"errorMessage":"button layout string {:?} contains no valid buttons (unrecognized: {})","messagePattern":"button layout string (.+?) contains no valid buttons \\(unrecognized: (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/gpui/src/platform.rs","lineNumber":727,"sourceCode":"                    }\n                }\n            }\n            result\n        }\n\n        let (left_str, right_str) = layout_string.split_once(':').unwrap_or((\"\", layout_string));\n        let mut unrecognized = Vec::new();\n        let mut seen_buttons = [false; MAX_BUTTONS_PER_SIDE];\n        let layout = Self {\n            left: parse_side(left_str, &mut seen_buttons, &mut unrecognized),\n            right: parse_side(right_str, &mut seen_buttons, &mut unrecognized),\n        };\n\n        if !unrecognized.is_empty()\n            && layout.left.iter().all(Option::is_none)\n            && layout.right.iter().all(Option::is_none)\n        {\n            bail!(\n                \"button layout string {:?} contains no valid buttons (unrecognized: {})\",\n                layout_string,\n                unrecognized.join(\", \")\n            );\n        }\n\n        Ok(layout)\n    }\n\n    /// Formats the layout back into a GNOME-style `button-layout` string.\n    #[cfg(test)]\n    pub fn format(&self) -> String {\n        fn format_side(buttons: &[Option<WindowButton>; MAX_BUTTONS_PER_SIDE]) -> String {\n            buttons\n                .iter()\n                .flatten()\n                .map(|button| match button {\n                    WindowButton::Minimize => \"minimize\",","sourceCodeStart":709,"sourceCodeEnd":745,"githubUrl":"https://github.com/zed-industries/zed/blob/9d272b036335401f339d024ea94968fd51016c40/crates/gpui/src/platform.rs#L709-L745","documentation":"WindowButtonLayout::parse reads a GNOME-style 'button-layout' string ('left:right', e.g. 'close,minimize:maximize'). Only the tokens 'minimize', 'maximize' and 'close' are recognized; unknown tokens are collected, and the parse fails only when every token on both sides was unrecognized — i.e. the string yields no usable buttons at all. Partial garbage is tolerated.","triggerScenarios":"Passing a string whose every comma-separated token is unknown: 'foo:bar', ':qux', or a whole string like 'Close,Minimize' where capitalized tokens do not match the lowercase names. With no ':' present, the entire string is parsed as the right side.","commonSituations":"Reading gtk-decoration-layout or gsettings values containing unexpected or locale-specific tokens; hand-rolled config using invented button names; casing mismatches when transcribing GNOME settings.","solutions":["Use the recognized lowercase names: minimize, maximize, close (e.g. 'close,minimize:maximize')","Fix casing and separators — tokens are lowercase and comma-separated per side","If the value comes from the desktop environment, normalize it before passing in, or fall back to WindowButtonLayout::linux_default()"],"exampleFix":"// before\nlet layout = WindowButtonLayout::parse(\"Close,Minimize\")?; // capitalized -> all unrecognized -> bail\n\n// after\nlet layout = WindowButtonLayout::parse(\"close,minimize:maximize\")?;","handlingStrategy":"validation","validationCode":"const KNOWN_BUTTONS: &[&str] = &[\"minimize\", \"maximize\", \"close\"];\nfn plausible_layout(s: &str) -> bool {\n    s.split(':')\n        .flat_map(|side| side.split(','))\n        .any(|token| KNOWN_BUTTONS.contains(&token.trim()))\n}","typeGuard":null,"tryCatchPattern":"let layout = WindowButtonLayout::parse(raw).unwrap_or_else(|err| {\n    log::warn!(\"unusable button-layout '{raw}': {err}; using default\");\n    WindowButtonLayout::linux_default()\n});","preventionTips":["Keep button-layout tokens lowercase and comma-separated per side","Only use minimize/maximize/close","Fall back to linux_default() when parsing externally sourced values"],"tags":["gpui","linux","window-management","settings","titlebar"],"backgroundTag":"invalid-setting-value","analyzedSha":"9d272b036335401f339d024ea94968fd51016c40","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}