{"record":{"id":"0a5ce3448f7c54bf","repo":"atuinsh/atuin","slug":"failed-to-open-editor","errorCode":null,"errorMessage":"failed to open editor","messagePattern":"failed to open editor","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin/src/command/client/scripts.rs","lineNumber":144,"sourceCode":"        // Create a temporary file\n        let temp_file = NamedTempFile::new()?;\n        let path = temp_file.into_temp_path();\n\n        // Write initial content to the temp file if provided\n        if let Some(content) = initial_content {\n            std::fs::write(&path, content)?;\n        }\n\n        // Open the file in the user's preferred editor\n        let editor_str = std::env::var(\"EDITOR\").unwrap_or_else(|_| \"vi\".to_string());\n\n        // Use shlex to safely split the string into shell-like parts.\n        let parts = shlex::split(&editor_str).ok_or_eyre(\"Failed to parse editor command\")?;\n        let (command, args) = parts.split_first().ok_or_eyre(\"No editor command found\")?;\n\n        let status = std::process::Command::new(command).args(args).arg(&path).status()?;\n        if !status.success() {\n            bail!(\"failed to open editor\");\n        }\n\n        // Read back the edited content\n        let content = std::fs::read_to_string(&path)?;\n        path.close()?;\n\n        Ok(content)\n    }\n\n    // Helper function to execute a script and manage stdin/stdout/stderr\n    async fn execute_script(script_content: String, shebang: String) -> Result<i32> {\n        let mut session = execute_script_interactive(script_content, shebang)\n            .await\n            .expect(\"failed to execute script\");\n\n        // Create a channel to signal when the process exits\n        let (exit_tx, mut exit_rx) = tokio::sync::oneshot::channel();\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/atuinsh/atuin/blob/c0c717ab04c881764bcad4b3d169a507e2432643/crates/atuin/src/command/client/scripts.rs#L126-L162","documentation":"Atuin's script editor launcher spawns the configured editor via `std::process::Command` and checks the resulting exit status. When the editor process runs but exits with a non-zero status, `bail!(\"failed to open editor\")` aborts the operation. This typically means the editor itself failed (bad terminal, unsupported flags, editor crashed) rather than atuin being unable to find the editor binary.","triggerScenarios":"Calling any atuin scripts subcommand that opens an editor (e.g. `atuin scripts new` without `--no-edit`, `atuin scripts edit`) where `$EDITOR`/configured editor launches but exits non-zero.","commonSituations":"EDITOR set to a GUI editor that fails without a display (e.g. `code --wait` without VS Code running properly), editor opening in a non-interactive/captured-stdio context, editor crashing on the temp file, or the user quitting the editor with an error exit code.","solutions":["Verify $EDITOR/$VISUAL works: run `\"$EDITOR\" <file>` manually on a test file and check its exit code.","Set a known-good terminal editor: `export EDITOR=vim` (or nano/emacs) in your shell profile.","If using a GUI editor, add the wait flag it requires (e.g. `code --wait`) so the process exits correctly after editing.","Use `--no-edit` on `atuin scripts new` to skip the editor entirely and pipe/author content another way.","Run atuin in an interactive terminal so the editor gets a usable TTY."],"exampleFix":"// before\nexport EDITOR=\"code\"\n// after\nexport EDITOR=\"code --wait\"  # or a terminal editor: export EDITOR=vim","handlingStrategy":"validation","validationCode":"// shell\nif [ -n \"$EDITOR\" ] && ! command -v \"${EDITOR%% *}\" >/dev/null 2>&1; then\n  echo \"EDITOR '$EDITOR' not available\" >&2\nfi\n# also test: \"$EDITOR\" /tmp/probe.txt && echo editor-ok || echo editor-fails","typeGuard":null,"tryCatchPattern":"// in a wrapper script\nif ! atuin scripts new \"my cmd\"; then\n  echo \"editor failed; retry with --no-edit\" >&2\n  atuin scripts new --no-edit \"my cmd\"\nfi","preventionTips":["Set EDITOR to a terminal editor present on every machine you use (vim/nano).","For GUI editors always include the wait flag (e.g. `code --wait`).","Test the editor on a scratch file after changing EDITOR.","Run atuin commands from an interactive TTY, not from captured-output contexts."],"tags":["editor","cli","subprocess-exit-code"],"backgroundTag":"git-command-failed","analyzedSha":"c0c717ab04c881764bcad4b3d169a507e2432643","analyzedAt":"2026-09-12T07:40:01.341Z","contentChangedAt":"2026-09-12T07:40:01.341Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}