zed-industries/zed · warning
button layout string {:?} contains no valid buttons (unrecog
Error message
button layout string {:?} contains no valid buttons (unrecognized: {}) What it means
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.
Source
Thrown at crates/gpui/src/platform.rs:727
}
}
}
result
}
let (left_str, right_str) = layout_string.split_once(':').unwrap_or(("", layout_string));
let mut unrecognized = Vec::new();
let mut seen_buttons = [false; MAX_BUTTONS_PER_SIDE];
let layout = Self {
left: parse_side(left_str, &mut seen_buttons, &mut unrecognized),
right: parse_side(right_str, &mut seen_buttons, &mut unrecognized),
};
if !unrecognized.is_empty()
&& layout.left.iter().all(Option::is_none)
&& layout.right.iter().all(Option::is_none)
{
bail!(
"button layout string {:?} contains no valid buttons (unrecognized: {})",
layout_string,
unrecognized.join(", ")
);
}
Ok(layout)
}
/// Formats the layout back into a GNOME-style `button-layout` string.
#[cfg(test)]
pub fn format(&self) -> String {
fn format_side(buttons: &[Option<WindowButton>; MAX_BUTTONS_PER_SIDE]) -> String {
buttons
.iter()
.flatten()
.map(|button| match button {
WindowButton::Minimize => "minimize",View on GitHub (pinned to 9d272b0363)
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()
Example fix
// before
let layout = WindowButtonLayout::parse("Close,Minimize")?; // capitalized -> all unrecognized -> bail
// after
let layout = WindowButtonLayout::parse("close,minimize:maximize")?; Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_BUTTONS: &[&str] = &["minimize", "maximize", "close"];
fn plausible_layout(s: &str) -> bool {
s.split(':')
.flat_map(|side| side.split(','))
.any(|token| KNOWN_BUTTONS.contains(&token.trim()))
} Try / catch
let layout = WindowButtonLayout::parse(raw).unwrap_or_else(|err| {
log::warn!("unusable button-layout '{raw}': {err}; using default");
WindowButtonLayout::linux_default()
}); Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- blocking sender returned without value
- invalid RGBA hex color: '{value}'. Expected #rgb, #rgba, #rr
- No GPU adapters found
- wl_seat below required version: {} < {}
- wl_output below required version: {} < {}
AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-08-20).
Data as JSON: /api/errors/cc3930d5948829ff.
Report an issue: GitHub.