{"record":{"id":"b8ac382f7bb96cd6","repo":"gitbutlerapp/gitbutler","slug":"editor-exited-with-non-zero-status-get-text","errorCode":null,"errorMessage":"Editor exited with non-zero status","messagePattern":"Editor exited with non-zero status","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/tui/get_text.rs","lineNumber":120,"sourceCode":"        if !initial_text.ends_with('\\n') {\n            writeln!(&mut tempfile)?;\n        }\n        writeln!(&mut tempfile, \"{REST_TEXT_MARKER}\")?;\n        writeln!(&mut tempfile, \"{rest_text}\")?;\n    }\n\n    // The editor command is allowed to be a shell expression, e.g. \"code --wait\" is somewhat common.\n    // We need to execute within a shell to make sure we don't get \"No such file or directory\" errors.\n    let status = gix::command::prepare(editor_cmd)\n        .arg(tempfile.path())\n        .stdin(std::process::Stdio::inherit())\n        .stdout(std::process::Stdio::inherit())\n        .with_shell()\n        .spawn()?\n        .wait()?;\n\n    if !status.success() {\n        return Err(anyhow::anyhow!(\"Editor exited with non-zero status\")\n            .context(Code::EditorExitedWithNonZeroStatus));\n    }\n\n    Ok(std::fs::read(&tempfile)\n        .context(\"failed to read contents of commit message file\")?\n        .into())\n}\n\n/// Launch the built-in TUI editor.\nfn from_builtin_editor(\n    filename_safe_intent: &str,\n    initial_text: &str,\n    rest_text: Option<&str>,\n) -> Result<BString> {\n    // Determine editor mode based on the intent\n    let mode = if filename_safe_intent.contains(\"commit\") {\n        super::editor::EditorMode::CommitMessage\n    } else if filename_safe_intent.contains(\"branch\") {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/tui/get_text.rs#L102-L138","documentation":"When building a commit message from an external editor (`from_external_editor`), the CLI spawns the editor via a shell, inherits stdio, and waits for it. If the editor process exits with a non-zero status, this error (with code EditorExitedWithNonZeroStatus) is returned instead of reading the temp file.","triggerScenarios":"The configured GIT_EDITOR/core.editor exits non-zero — editor crashed, user aborted in vim with :cq, editor binary not found under the invoked name, or the editor wrote to a read-only temp file.","commonSituations":"vim/nvim `:cq` usage; bad EDITOR variable pointing to a non-executable or missing program; editor opening a GUI and failing silently; shell wrapper quoting issues.","solutions":["Set a known-good editor: `export EDITOR=vim` (or nano/code) and retry.","In vim, exit normally with :wq instead of :cq.","Verify the editor binary exists and is executable (`which $EDITOR`).","If the failure persists, write the message directly with a non-interactive flag (e.g. `but commit -m \"message\"`) to bypass the editor."],"exampleFix":"// before\nEDITOR=emacsclient git-style editor launch fails\n// after\nexport EDITOR=\"emacsclient -a nano\"\nbut commit","handlingStrategy":"try-catch","validationCode":"const ed = process.env.EDITOR || process.env.GIT_EDITOR;\nif (!ed || !commandExists(ed.split(' ')[0])) console.warn(`editor '${ed}' not found; set EDITOR to an installed editor`);","typeGuard":null,"tryCatchPattern":"match CommitMessage::from_editor(&tempfile) {\n  Err(e) if e.to_string().contains(\"non-zero status\") => {\n    eprintln!(\"editor failed; check EDITOR and exit the editor normally (:wq, not :cq)\");\n    Err(e)\n  }\n  other => other,\n}","preventionTips":["Pin EDITOR to a known-working, installed editor.","Never abort editors with :cq/:q! when the CLI should proceed.","Use -m flags in non-interactive/CI contexts to skip the editor entirely."],"tags":["editor","process","cli","commit-message"],"backgroundTag":"command-not-found","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}