affaan-m/ECC · error · anyhow::Error

{program} exited with {status}

Error message

{program} exited with {status}

What it means

Thrown by run_notification_command (non-test build) after it successfully launches the configured notify program but that program exits with a non-zero status. The command ran but signaled failure, so the notification is treated as failed.

Source

Thrown at ecc2/src/notifications.rs:395

            "content": message,
            "allowed_mentions": {
                "parse": []
            }
        }),
    }
}

#[cfg(not(test))]
fn run_notification_command(program: &str, args: &[String]) -> Result<()> {
    let status = std::process::Command::new(program)
        .args(args)
        .status()
        .with_context(|| format!("launch {program}"))?;

    if status.success() {
        Ok(())
    } else {
        anyhow::bail!("{program} exited with {status}");
    }
}

#[cfg(test)]
fn run_notification_command(_program: &str, _args: &[String]) -> Result<()> {
    Ok(())
}

#[cfg(not(test))]
fn send_webhook_request(target: &WebhookTarget, payload: serde_json::Value) -> Result<()> {
    let agent = ureq::Agent::config_builder()
        .timeout_connect(Some(std::time::Duration::from_secs(5)))
        .timeout_recv_response(Some(std::time::Duration::from_secs(5)))
        .build()
        .new_agent();
    let response = agent
        .post(&target.url)
        .send_json(payload)

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Run the exact notify command and args manually in the same environment and observe its exit code and stderr.
  2. Fix the script so it exits 0 on success; surface real failures with a clear non-zero code.
  3. Ensure the program path is absolute or resolvable on the service's PATH, and the file is executable.
  4. Check the status value in the message: on Unix, code > 128 means the program was killed by a signal (e.g. 137 = SIGKILL, often OOM).
  5. If the script legitimately warns but should still succeed, make it exit 0 and log the warning instead.

Example fix

# before: notify.sh exits non-zero on a harmless warning
#!/bin/sh
notify-send "$1" || exit 1

# after: treat a missing notify-send as best-effort
#!/bin/sh
notify-send "$1" 2>/dev/null || true
exit 0
Defensive patterns

Strategy: try-catch

Validate before calling

use std::path::Path;
fn notify_program_runnable(program: &str) -> bool {
    Path::new(program).is_absolute() && Path::new(program).is_file()
        || which::which(program).is_ok()
}

Try / catch

if let Err(e) = run_notification_command(program, args) {
    log::warn!("notification command {program} failed: {e:#}; notification skipped");
}

Prevention

When it happens

Trigger: A custom notification command (e.g. a shell script, sendmail, or osascript wrapper) configured in notifications exits non-zero: the script has a bug, references a missing binary, fails an internal check, or returns a non-zero code on success by mistake.

Common situations: A notify script missing its shebang or not executable; the script calls a binary not on PATH in the service's environment; a script that does 'exit 1' on a minor warning; permission errors writing a log file inside the script.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/bcb82a72d922b76b. Report an issue: GitHub.