Hmbown/CodeWhale · error

editor exited with

Error message

editor {editor:?} exited with {status}

What it means

When running the config editor subcommand (e.g. `codewhale config edit`), the CLI spawns $VISUAL/$EDITOR (defaulting to vi) on the config file and checks its exit status. If the editor process terminates with a nonzero status, the command reports the editor and its status via this error.

Solutions

  1. Re-run and check the editor's own output for its error message.
  2. Verify $VISUAL/$EDITOR points to a working editor: `echo $EDITOR` and try opening the file directly.
  3. Fall back to a known-good editor: `EDITOR=vi codewhale config edit` (or nano).
  4. Edit the config file manually with any editor instead of the subcommand.

Example fix

// before
$EDITOR='my-broken-wrapper' codewhale config edit
// after
EDITOR=vim codewhale config edit
Defensive patterns

Strategy: try-catch

Validate before calling

let editor = std::env::var("VISUAL").or_else(|_| std::env::var("EDITOR")).unwrap_or_else(|_| "vi".into());
if which::which(&editor).is_err() {
    eprintln!("editor '{editor}' not found; set $EDITOR to a working editor");
}

Try / catch

if let Err(e) = run_config_edit() {
    if let Some(status) = extract_editor_status(&e) {
        eprintln!("editor failed with {status}; fix the file manually or choose another $EDITOR");
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: The editor binary launched successfully (status() returned Ok) but exited with status.success() == false — e.g. the editor crashed, the file failed validation inside the editor, or a save failed.

Common situations: Misconfigured EDITOR pointing to a wrapper script that fails; editor refusing to open an unreadable file path; exiting vi/vim with :cq or a forced quit with an error; disk-full or permission errors inside the editor.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/14f2cda1d0d62b3e. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/lib.rs:4642

            }
            Ok(())
        }
        ConfigCommand::Path => {
            println!("{}", store.path().display());
            Ok(())
        }
        ConfigCommand::Edit => {
            let path = store.path().to_path_buf();
            println!("{}", path.display());
            let editor = std::env::var("VISUAL")
                .or_else(|_| std::env::var("EDITOR"))
                .unwrap_or_else(|_| "vi".to_string());
            let status = Command::new(&editor)
                .arg(&path)
                .status()
                .with_context(|| format!("failed to launch editor {editor:?}"))?;
            if !status.success() {
                bail!("editor {editor:?} exited with {status}");
            }
            Ok(())
        }
        ConfigCommand::Doctor => run_config_doctor(store),
        ConfigCommand::Dump => {
            if !per_run_overrides.is_empty() {
                println!(
                    "# {} per-run --set override(s), not saved",
                    per_run_overrides.len()
                );
            }
            println!("# {}", store.path().display());
            print!(
                "{}",
                toml::to_string_pretty(&store.config.redacted_toml_value())?
            );
            Ok(())
        }

View on GitHub (pinned to 73e0f67d83)