astrid-runtime/astrid · error
editor '{editor}' exited with non-zero status
Error message
editor '{editor}' exited with non-zero status What it means
`astrid config edit` launches the user's editor (from $EDITOR/$VISUAL, defaulting to vi) on the config file and requires a zero exit status. This error is thrown when the editor process ran but returned a non-zero code, meaning the editor itself reported a problem (user abort, unsavable file, bad editor config).
Source
Thrown at crates/astrid-cli/src/commands/config.rs:75
let home = astrid_core::dirs::AstridHome::resolve()
.map_err(|e| anyhow::anyhow!("Failed to resolve Astrid home: {e}"))?;
let path = home.config_path();
if !path.exists() {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(&path, "# Astrid runtime configuration\n")?;
}
let editor = std::env::var("EDITOR")
.ok()
.or_else(|| std::env::var("VISUAL").ok())
.unwrap_or_else(|| "vi".to_string());
let status = std::process::Command::new(&editor)
.arg(&path)
.status()
.map_err(|e| anyhow::anyhow!("Failed to launch '{editor}': {e}"))?;
if !status.success() {
anyhow::bail!("editor '{editor}' exited with non-zero status");
}
Ok(())
}
/// Show all config file paths that are checked.
#[expect(clippy::unnecessary_wraps)]
pub(crate) fn show_paths() -> Result<()> {
let home = directories::BaseDirs::new().map(|d| d.home_dir().to_string_lossy().to_string());
let workspace = std::env::current_dir()
.ok()
.map(|p| p.to_string_lossy().to_string());
let astrid_home = std::env::var("ASTRID_HOME").ok();
let paths = ResolvedConfig::config_paths_with_layout(
home.as_deref(),
astrid_home.as_deref(),
workspace.as_deref(),View on GitHub (pinned to affd8760f4)
Solutions
- Check what $EDITOR/$VISUAL is set to and pick a terminal editor that exits 0 on save: export EDITOR=vim (or nano) and retry.
- Open the config file manually at the printed path, edit it, and save.
- Check for write permission on the config file and fix ownership/permissions if the editor failed to save.
- If the editor exit is intentional-abort behavior, ignore the error — the config was not changed.
Example fix
// before $ EDITOR=code astrid config edit # GUI editor returns non-zero in CI // after $ export EDITOR=vim $ astrid config edit # OK
Defensive patterns
Strategy: validation
Validate before calling
// Validate the editor before launching it
fn editor_ok(editor: &str) -> bool {
match std::process::Command::new(editor).arg("--version").status() {
Ok(s) => s.success(),
Err(_) => false,
}
} Try / catch
let status = std::process::Command::new(&editor).arg(&path).status()
.map_err(|e| anyhow::anyhow!("Failed to launch '{editor}': {e}"))?;
if !status.success() {
eprintln!("editor '{editor}' exited with {} (config unchanged); set $EDITOR to a terminal editor and retry",
status.code().unwrap_or(-1));
return Ok(()); // treat abort as no-op instead of a hard error
} Prevention
- Set $EDITOR/$VISUAL to a terminal editor (vim, nano) that accepts a file path and exits 0 on save.
- In scripts/CI, prefer `astrid config set key value` over interactive editing.
- Ensure the config file is writable by the user running the editor.
- Remember vi's :cq exits non-zero by design — use :wq or :q! instead.
When it happens
Trigger: Running `astrid config edit` (edit_config) where the spawned editor command exits with status != 0 — e.g. the user quits vi with :cq, nano fails to write, or the editor errors on the file.
Common situations: EDITOR set to a GUI app or a program that doesn't accept a file argument; user intentionally aborts in vi with :cq; editor lacks write permission on the config path; misconfigured editor plugin failing at startup.
Related errors
- invalid value for {capsule_id}.{key}: expected one of {}, go
- ps failed while inspecting MCP processes
- ASTRID_ENFORCED_DISTRO must not be empty
- git could not inspect captured version: {}
- failed to format config: {e}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/426fab13c253d03d.
Report an issue: GitHub.