{"record":{"id":"e35db47ed455b326","repo":"gitbutlerapp/gitbutler","slug":"cannot-handle-changes-while-in-edit-mode-please-e","errorCode":null,"errorMessage":"Cannot handle changes while in edit mode. Please exit edit mode first.","messagePattern":"Cannot handle changes while in edit mode\\. Please exit edit mode first\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-action/src/lib.rs","lineNumber":126,"sourceCode":"            snapshot_after,\n            &response,\n        )?\n    };\n    response.map(|outcome| (id, outcome))\n}\n\n/// Prepare repository state for handle-changes.\n///\n/// This preserves the legacy preconditions from the old context-owning action flow:\n/// ensure a default target exists, reject edit mode, and switch back to the workspace\n/// branch when the repository is currently outside the workspace. Callers must hold\n/// exclusive worktree access and pass its permission through so no nested guard is\n/// acquired here.\nfn prepare_handle_changes(ctx: &mut Context, perm: &mut RepoExclusive) -> anyhow::Result<()> {\n    default_target_setting_if_none(ctx)?;\n    match gitbutler_operating_modes::operating_mode(ctx, perm.read_permission())? {\n        OperatingMode::OpenWorkspace => Ok(()),\n        OperatingMode::Edit(_) => Err(anyhow::anyhow!(\n            \"Cannot handle changes while in edit mode. Please exit edit mode first.\"\n        )),\n        OperatingMode::OutsideWorkspace(_) => {\n            let target_ref: gitbutler_reference::RemoteRefname = ctx\n                .project_meta()?\n                .target_ref_or_err()?\n                .to_string()\n                .parse()?;\n            gitbutler_branch_actions::set_base_branch(ctx, &target_ref, perm).map(|_| ())\n        }\n    }\n}\n\nfn default_target_setting_if_none(ctx: &Context) -> anyhow::Result<()> {\n    if ctx.project_meta()?.target_ref.is_some() {\n        return Ok(());\n    }\n    // Lets do the equivalent of `git symbolic-ref refs/remotes/origin/HEAD --short` to guess the default target.","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but-action/src/lib.rs#L108-L144","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Exit edit mode first (the GitButler workspace 'exit edit mode' control) and retry the operation.","If scripting, check the operating mode before invoking handle-changes and abort with guidance instead of surfacing the raw error.","In the frontend, disable the handle-changes entry point while the mode is Edit and subscribe to mode-change events."],"exampleFix":"// before: unconditional call\nlet outcome = handle_changes(...)?;\n\n// after: mode precondition\nuse gitbutler_operating_modes::{operating_mode, OperatingMode};\nif matches!(operating_mode(ctx, perm.read_permission())?, OperatingMode::Edit(_)) {\n    anyhow::bail!(\"exit edit mode before running handle-changes\");\n}\nlet outcome = handle_changes(...)?;","handlingStrategy":"validation","validationCode":"use gitbutler_operating_modes::{operating_mode, OperatingMode};\n\nfn can_handle_changes(ctx: &Context, perm: &RepoExclusiveRead) -> anyhow::Result<bool> {\n    Ok(matches!(operating_mode(ctx, perm)?, OperatingMode::OpenWorkspace))\n}","typeGuard":"fn blocks_handle_changes(mode: &OperatingMode) -> bool {\n    matches!(mode, OperatingMode::Edit(_))\n}","tryCatchPattern":"match handle_changes_flow(ctx) {\n    Err(err) if err.to_string().contains(\"while in edit mode\") => {\n        prompt_exit_edit_mode(); // re-run only after the user confirms exit\n    }\n    other => other?,\n}","preventionTips":["Check or subscribe to operating-mode state before enabling agent commit actions.","Wrap agent flows with a mode precondition so users get a targeted prompt.","Never auto-exit edit mode on the user's behalf; always ask."],"tags":["edit-mode","operating-mode","workspace","precondition","agent-action"],"backgroundTag":"operation-not-allowed-in-current-mode","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}