gitbutlerapp/gitbutler · error

Cannot handle changes while in edit mode. Please exit edit m

Error message

Cannot handle changes while in edit mode. Please exit edit mode first.

What it means

The 'handle changes' action (which commits uncommitted changes across stacks) refuses to run while the project is in GitButler's Edit operating mode, where the user works directly on the gitbutler/workspace branch outside normal virtual-branch mechanics. prepare_handle_changes checks the operating mode first and bails with this message on OperatingMode::Edit so the action never fights the user's direct edits.

Source

Thrown at crates/but-action/src/lib.rs:126

            snapshot_after,
            &response,
        )?
    };
    response.map(|outcome| (id, outcome))
}

/// Prepare repository state for handle-changes.
///
/// This preserves the legacy preconditions from the old context-owning action flow:
/// ensure a default target exists, reject edit mode, and switch back to the workspace
/// branch when the repository is currently outside the workspace. Callers must hold
/// exclusive worktree access and pass its permission through so no nested guard is
/// acquired here.
fn prepare_handle_changes(ctx: &mut Context, perm: &mut RepoExclusive) -> anyhow::Result<()> {
    default_target_setting_if_none(ctx)?;
    match gitbutler_operating_modes::operating_mode(ctx, perm.read_permission())? {
        OperatingMode::OpenWorkspace => Ok(()),
        OperatingMode::Edit(_) => Err(anyhow::anyhow!(
            "Cannot handle changes while in edit mode. Please exit edit mode first."
        )),
        OperatingMode::OutsideWorkspace(_) => {
            let target_ref: gitbutler_reference::RemoteRefname = ctx
                .project_meta()?
                .target_ref_or_err()?
                .to_string()
                .parse()?;
            gitbutler_branch_actions::set_base_branch(ctx, &target_ref, perm).map(|_| ())
        }
    }
}

fn default_target_setting_if_none(ctx: &Context) -> anyhow::Result<()> {
    if ctx.project_meta()?.target_ref.is_some() {
        return Ok(());
    }
    // Lets do the equivalent of `git symbolic-ref refs/remotes/origin/HEAD --short` to guess the default target.

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Exit edit mode first (the GitButler workspace 'exit edit mode' control) and retry the operation.
  2. If scripting, check the operating mode before invoking handle-changes and abort with guidance instead of surfacing the raw error.
  3. In the frontend, disable the handle-changes entry point while the mode is Edit and subscribe to mode-change events.

Example fix

// before: unconditional call
let outcome = handle_changes(...)?;

// after: mode precondition
use gitbutler_operating_modes::{operating_mode, OperatingMode};
if matches!(operating_mode(ctx, perm.read_permission())?, OperatingMode::Edit(_)) {
    anyhow::bail!("exit edit mode before running handle-changes");
}
let outcome = handle_changes(...)?;
Defensive patterns

Strategy: validation

Validate before calling

use gitbutler_operating_modes::{operating_mode, OperatingMode};

fn can_handle_changes(ctx: &Context, perm: &RepoExclusiveRead) -> anyhow::Result<bool> {
    Ok(matches!(operating_mode(ctx, perm)?, OperatingMode::OpenWorkspace))
}

Type guard

fn blocks_handle_changes(mode: &OperatingMode) -> bool {
    matches!(mode, OperatingMode::Edit(_))
}

Try / catch

match handle_changes_flow(ctx) {
    Err(err) if err.to_string().contains("while in edit mode") => {
        prompt_exit_edit_mode(); // re-run only after the user confirms exit
    }
    other => other?,
}

Prevention

When it happens

Trigger: Invoking the handle-changes flow (but-action::handle_changes and its but-api wrappers, e.g. the AI 'handle changes' command) while gitbutler_operating_modes::operating_mode reports OperatingMode::Edit — the user entered edit mode on the workspace and has not exited yet.

Common situations: User enters edit mode to hand-edit the workspace branch in git and forgets to exit, then triggers an agent commit flow; automation scripts running while the user is mid-edit; frontend that does not refresh the mode before enabling the action.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/e35db47ed455b326. Report an issue: GitHub.