sinelaw/fresh · error

no split layout

Error message

no split layout

What it means

preview_file_in_split needs to know the active split of the current window to open a preview, but the window has no split layout (single leaf, no split tree). buffer_management.rs:279 uses ok_or_else on splits()/active_split() and bails with "no split layout".

Solutions

  1. Create a split (split_vertical/split_horizontal) before requesting an in-split preview
  2. Fall back to a regular preview/open in the current pane when no split layout exists
  3. Guard the command: check for an existing split layout and disable the in-split preview action otherwise

Example fix

// before
let id = editor.preview_file_in_split(path)?; // fails without splits
// after
if editor.has_split_layout() {
    let id = editor.preview_file_in_split(path)?;
} else {
    let id = editor.preview_file(path)?;
}
Defensive patterns

Strategy: fallback

Validate before calling

let has_splits = editor.active_window_splits().is_some();
if !has_splits { editor.split_horizontal()?; }

Type guard

fn can_preview_in_split(editor: &Editor) -> bool {
    editor.active_window_splits().is_some()
}

Try / catch

match editor.preview_file_in_split(path) {
    Err(e) if e.to_string() == "no split layout" => editor.preview_file(path),
    other => other,
}

Prevention

When it happens

Trigger: Calling preview_file_in_split (via handle_preview_file_in_split) when the active window's buffer tree has no splits — windows.get(...).and_then(splits) yields None or active_split() is unavailable.

Common situations: Preview keybinding/command executed in a fresh single-pane window before any split was created; scripted automation assuming splits exist; after closing all splits except one.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/96dd89496ae70f09. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/src/app/buffer_management.rs:279

    /// handler on purpose: the focus handler commits the preview when it
    /// moves between splits ("walking away is commitment"), which is right
    /// for a user walking away and wrong for a browse that never left. Same
    /// reason the cursor jump happens inside the window: `jump_to_line_column`
    /// moves the active split's cursor, and the target is the active split
    /// only until this returns.
    pub fn preview_file_in_split(
        &mut self,
        path: &Path,
        target_split: LeafId,
        line: Option<usize>,
        column: Option<usize>,
    ) -> anyhow::Result<BufferId> {
        let previous_split = self
            .windows
            .get(&self.active_window)
            .and_then(|w| w.buffers.splits())
            .map(|(mgr, _)| mgr.active_split())
            .ok_or_else(|| anyhow::anyhow!("no split layout"))?;

        let set_active = |editor: &mut Self, split: LeafId| -> bool {
            editor
                .windows
                .get_mut(&editor.active_window)
                .and_then(|w| w.split_manager_mut())
                .is_some_and(|mgr| mgr.set_active_split(split))
        };

        if !set_active(self, target_split) {
            anyhow::bail!("preview: split {:?} does not exist", target_split);
        }

        let result = self.preview_file(path);
        if result.is_ok() && (line.is_some() || column.is_some()) {
            self.jump_to_line_column(line, column);
        }

View on GitHub (pinned to 67894ca546)