{"record":{"id":"501368a3c4d53d54","repo":"aaif-goose/goose","slug":"editor-exited-with-non-zero-status","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/goose-cli/src/session/editor.rs","lineNumber":182,"sourceCode":"        return Err(anyhow::anyhow!(\"Empty editor command\"));\n    }\n\n    let mut cmd = Command::new(&parts[0]);\n    if let Ok(cwd) = std::env::current_dir() {\n        cmd.current_dir(cwd);\n    }\n    if parts.len() > 1 {\n        cmd.args(&parts[1..]);\n    }\n    cmd.arg(file_path)\n        .stdin(Stdio::inherit())\n        .stdout(Stdio::inherit())\n        .stderr(Stdio::inherit());\n\n    let status = cmd.status()?;\n\n    if !status.success() {\n        return Err(anyhow::anyhow!(\n            \"Editor exited with non-zero status: {}\",\n            status.code().unwrap_or(-1)\n        ));\n    }\n\n    Ok(())\n}\n\n/// Main function to get input from editor\npub fn get_editor_input(\n    editor_cmd: &str,\n    messages: &[&str],\n    prefill: Option<&str>,\n) -> Result<(String, bool)> {\n    let temp_file = create_temp_file(messages, prefill)?;\n    let temp_path = temp_file.path().to_path_buf();\n\n    let symlink_path = PathBuf::from(\".goose_prompt_temp.md\");","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/session/editor.rs#L164-L200","documentation":"goose spawns the user's $EDITOR/$VISUAL on a temp file to collect multi-line prompt input (editor.rs). After the child process exits, its exit status is checked; any non-zero exit code produces this error and the edited file is not accepted. The number in the message is the raw exit code (-1 when the process was killed by a signal).","triggerScenarios":"Any path that opens the editor for input (interactive CLI editor flow via get_editor_input / launch_editor) where the editor exits non-zero: quitting vim with :cq, an EDITOR wrapper script that exits 1, or an editor binary that crashes on startup.","commonSituations":"EDITOR/VISUAL pointing at a missing or broken binary; the user aborting the editor deliberately; containers/CI without a usable editor; terminal multiplexer issues breaking the spawned editor.","solutions":["Re-open the editor and quit with a success status (vim :wq instead of :cq)","Verify $EDITOR/$VISUAL resolves to an installed, working binary: echo $EDITOR && $EDITOR --version","Use inline multi-line input instead of the editor in environments that cannot host one","If the exit was an intentional abort, treat this error as a user cancellation at the call site instead of a hard failure"],"exampleFix":"// before\nlet text = get_editor_input(editor_cmd, &[])?;\n// after\nmatch get_editor_input(editor_cmd, &[]) {\n    Ok(text) => { /* use text */ }\n    Err(e) if e.to_string().contains(\"non-zero status\") => return Ok(()), // user aborted\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":"use std::process::Command;\n\nfn editor_works(editor_cmd: &str) -> bool {\n    let mut parts = editor_cmd.split_whitespace();\n    let bin = match parts.next() { Some(b) => b, None => return false };\n    Command::new(bin).arg(\"--version\").output().is_ok()\n}","typeGuard":null,"tryCatchPattern":"match get_editor_input(editor_cmd, &[]) {\n    Ok(text) => { /* use text */ }\n    Err(e) if e.to_string().contains(\"non-zero status\") => {\n        // editor aborted: treat as user cancellation, not a crash\n        return Ok(());\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Set EDITOR to a simple, non-blocking binary (vim, nano) in scripts and containers","Quit editors with a success status (:wq), never :cq, when input should be kept","Wrap editor flows so a non-zero exit maps to a cancel action rather than a fatal error"],"tags":["cli","editor","subprocess","user-input"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}