gitbutlerapp/gitbutler · warning
Editor exited with non-zero status
Error message
Editor exited with non-zero status
What it means
Thrown by the legacy `but reword` flow when a commit message is edited in the user's Git editor. `get_commit_message_from_editor_legacy` launches the configured editor, and when the editor process exits with a non-zero status the underlying `but_error::Code::EditorExitedWithNonZeroStatus` is flattened into this plain anyhow message. A non-zero editor exit is the standard Git convention for deliberately aborting an edit (e.g. `:cq` in vim), so this usually means 'user cancelled', not corruption.
Source
Thrown at crates/but/src/command/legacy/reword2.rs:326
fn edit_commit_message(
repo: &gix::Repository,
context_lines: u32,
commit_details: CommitDetails,
editor_initial_message: &str,
current_message_for_comparison: &str,
) -> anyhow::Result<Option<String>> {
get_commit_message_from_editor_legacy(
repo,
context_lines,
commit_details,
editor_initial_message.to_owned(),
current_message_for_comparison,
ShowDiffInEditor::Unspecified,
)
.map_err(|err| {
if let Some(Code::EditorExitedWithNonZeroStatus) = err.downcast_ref::<but_error::Code>() {
anyhow::anyhow!("Editor exited with non-zero status")
} else {
err
}
})
}
pub enum RewordOperation {
Commit {
target: CommitId,
new_message: CommitMessageSource,
},
FormatCommit {
target: CommitId,
},
Branch {
target: FullName,
new_name: BranchNameSource,
},View on GitHub (pinned to caf1f223d3)
Solutions
- If the abort was intentional, just rerun the command and either save the buffer or pass the message directly with the -m/--message flag
- Test the configured editor outside `but`: `git var GIT_EDITOR` then launch that command by hand to confirm it exits 0 when saved
- In scripts and CI, always pass -m "new message" so no editor is spawned at all
- In wrappers, treat this specific error as a cancel (exit quietly) instead of surfacing a stack trace
Example fix
# before: opens an editor that may exit non-zero but reword c3 # after: non-interactive, no editor involved but reword c3 -m "fix: correct the commit message"
Defensive patterns
Strategy: try-catch
Validate before calling
let editor_spec = std::env::var("GIT_EDITOR")
.or_else(|_| std::env::var("VISUAL"))
.or_else(|_| std::env::var("EDITOR"))
.unwrap_or_else(|_| "vi".to_string());
let bin = editor_spec.split_whitespace().next().unwrap_or("");
if which::which(bin).is_err() {
eprintln!("configured editor '{bin}' is not on PATH; pass -m or fix core.editor");
} Type guard
fn is_editor_abort(err: &anyhow::Error) -> bool {
matches!(
err.downcast_ref::<but_error::Code>(),
Some(but_error::Code::EditorExitedWithNonZeroStatus)
) || err.to_string() == "Editor exited with non-zero status"
} Try / catch
match run_reword_with_editor(&mut ctx) {
Ok(Some(message)) => { /* use message */ }
Ok(None) => { /* unchanged */ }
Err(err) if is_editor_abort(&err) => {
// user cancelled in the editor; not a failure
return Ok(());
}
Err(err) => return Err(err),
} Prevention
- Always pass -m/--message in scripts and CI so no editor is spawned
- Verify core.editor / GIT_EDITOR launches and exits 0 by hand after changing it
- Treat editor non-zero exit as a cancel in wrappers, matching git's own convention
- Remember `:cq` in vim is the deliberate abort gesture; use `:wq` to accept
When it happens
Trigger: Running the legacy reword command with the Editor message source (no `-m` supplied) while GIT_EDITOR / core.editor / EDITOR returns a non-zero exit code: quitting vim with `:cq`, a VS Code `--wait` wrapper exiting 1, an editor killed by a signal, or a broken editor binary.
Common situations: User intentionally aborts the message edit with `:cq`; EDITOR points to a wrapper script that always exits non-zero; running reword in CI or a non-TTY session where the editor fails immediately; CI treated the abort as a hard failure.
Related errors
- The repository at {} is bare. GitButler requires a non-bare
- The repository at {} is a non-main worktree. GitButler requi
- The repository at {} has no working directory. GitButler req
- The repository at {} has no .git directory. GitButler requir
- The repository at {} uses the currently unsupported reftable
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/6054fc20d530904f.
Report an issue: GitHub.