GitoxideLabs/gitoxide · error
Git editor exited with
Error message
Git editor {editor_display} exited with {status} What it means
tix launches the configured Git editor (from `core.editor`/`GIT_EDITOR`) as a child process to let the user edit a commit-message document. If the editor process terminates with a non-zero exit status, the edit is treated as failed and this error is raised with the editor command and its status. The document on disk is discarded, so the operation should be retried.
Solutions
- Fix or replace the editor configured via `GIT_EDITOR`/`core.editor` (e.g. `git config core.editor vim`) and retry the operation.
- Check why the editor exits non-zero: run the same editor manually on a scratch file to reproduce and fix script errors.
- In non-interactive environments, use a non-interactive editor such as `GIT_EDITOR=true` or pipe the message instead of spawning an editor.
- Verify the editor script is executable and exits 0 on a successful save.
Example fix
// before: GIT_EDITOR points to a failing script GIT_EDITOR=./broken-editor.sh tix reword // error: Git editor ./broken-editor.sh exited with exit status: 1 // after: configure a working editor export GIT_EDITOR=vim # or for CI: export GIT_EDITOR=true
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: verify the editor is runnable before editing
let program = std::env::var("GIT_EDITOR").unwrap_or_else(|_| "vi".into());
assert!(which::which(program.split_whitespace().next().unwrap()).is_ok(),
"editor {program} not found"); Try / catch
// Rust
match edit_document_without_terminal(editor, doc, "COMMIT_EDITMSG") {
Ok(edited) => { /* proceed */ }
Err(e) if e.to_string().contains("exited with") => {
eprintln!("editor failed: {e}; fix GIT_EDITOR and retry");
}
Err(e) => return Err(e),
} Prevention
- Set `core.editor`/`GIT_EDITOR` to a known-working, executable editor.
- For scripts and CI, use `GIT_EDITOR=true` to avoid interactive editors entirely.
- Test wrapper editor scripts manually to ensure they exit 0 on success.
When it happens
Trigger: Calling `edit_document`/`edit_document_without_terminal` when the spawned editor command exits non-zero: the editor binary crashes, a terminal editor fails without a TTY, the user saves-and-quits with an error (e.g. vim `:cq`), or the configured editor script fails.
Common situations: `GIT_EDITOR` pointing to a missing or non-executable wrapper script; an editor like `vim` invoked with `:cq`; a GUI editor that cannot attach to the temp file; running inside an environment where the editor cannot open a terminal.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- we prohibit this
- Editor exited with
- Could not determine a remote for pushing
- Tried to use as tree, but was
- Tried to use as commit, but was
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/3cbed9cb487413b5.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/mod.rs:140
gix::tempfile::ContainingDirectory::Exists,
gix::tempfile::AutoRemove::Tempfile,
)
.context("could not create commit message file")?;
tempfile
.write_all(document)
.context("could not write commit message file")?;
tempfile.flush().context("could not flush commit message file")?;
let path = tempfile
.with_mut(|tempfile| tempfile.path().to_owned())
.context("commit message file disappeared")?;
let _tempfile = tempfile.close().context("could not close commit message file")?;
let editor_display = editor.command.to_string_lossy().into_owned();
let status = Command::from(editor.arg(&path))
.status()
.with_context(|| format!("could not launch Git editor {editor_display}"))?;
if !status.success() {
anyhow::bail!("Git editor {editor_display} exited with {status}");
}
let edited = std::fs::read(path).context("could not read edited commit message")?;
Ok((edited != document).then_some(edited))
}
#[cfg(test)]
mod tests {
use std::{path::Path, process::Command};
use super::*;
fn git(path: &Path, args: &[&str]) -> gix_testtools::Result<Vec<u8>> {
let output = Command::new("git").arg("-C").arg(path).args(args).output()?;
if !output.status.success() {
return Err(format!(
"git {} failed: {}",
args.join(" "),
String::from_utf8_lossy(&output.stderr)View on GitHub (pinned to e73179060b)