LGUG2Z/komorebi · error
custom layouts must be json or yaml files
Error message
custom layouts must be json or yaml files
What it means
CustomLayout::from_path loads a user-defined layout and only accepts .json, .yaml, or .yml extensions. Any other extension (or none) reaches the bail! arm with this message, aborting with an eyre error.
Solutions
- Rename the layout file to end with .json (or .yaml/.yml).
- Confirm the path passed via --layout or custom_layouts config points at the correct file.
- If the layout is in another format, convert it to JSON first.
Example fix
// before komorebic --layout ultrawide.txt // after komorebic --layout ultrawide.json
Defensive patterns
Strategy: validation
Validate before calling
let ext = std::path::Path::new(layout_path)
.extension()
.map(|e| e.to_string_lossy().to_lowercase());
assert!(matches!(ext.as_deref(), Some("json") | Some("yaml") | Some("yml")), "layout must be json or yaml"); Type guard
fn is_supported_layout(path: &std::path::Path) -> bool {
path.extension().map(|e| {
matches!(e.to_string_lossy().to_lowercase().as_str(), "json" | "yaml" | "yml")
}).unwrap_or(false)
} Try / catch
match CustomLayout::from_path(&path) {
Ok(l) => l,
Err(e) => eprintln!("layout load failed: {e}; use .json/.yaml/.yml"),
} Prevention
- Name custom layout files with .json/.yml extensions
- Check the --layout argument points at a real file with a supported extension
- Convert TOML/TXT layouts before use
When it happens
Trigger: Calling CustomLayout::from_path with a file whose extension is not json/yaml/yml, e.g. my_layout.txt, layout, or layout.json5. Referenced via komorebic --layout or static/dynamic layout config.
Common situations: Saving a downloaded layout without its extension; using .yason/.toml; text editor appending .txt; pointing --layout at documentation instead of the actual layout file.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of LGUG2Z/komorebi@e0709f02bf (2026-09-06).
Data as JSON: /api/errors/1acc01a04f27b90d.
Report an issue: GitHub.
Appendix: source
Thrown at komorebi-layouts/src/custom_layout.rs:42
}
impl DerefMut for CustomLayout {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl CustomLayout {
pub fn from_path<P: AsRef<Path>>(path: P) -> eyre::Result<Self> {
let path = path.as_ref();
let layout: Self = match path.extension() {
Some(extension) if extension == "yaml" || extension == "yml" => {
serde_json::from_reader(BufReader::new(File::open(path)?))?
}
Some(extension) if extension == "json" => {
serde_json::from_reader(BufReader::new(File::open(path)?))?
}
_ => bail!("custom layouts must be json or yaml files"),
};
if !layout.is_valid() {
bail!("the layout file provided was invalid");
}
Ok(layout)
}
#[must_use]
pub fn column_with_idx(&self, idx: usize) -> (usize, Option<&Column>) {
let column_idx = self.column_for_container_idx(idx);
let column = self.get(column_idx);
(column_idx, column)
}
#[must_use]
pub fn primary_idx(&self) -> Option<usize> {View on GitHub (pinned to e0709f02bf)