{"record":{"id":"bcb82a72d922b76b","repo":"affaan-m/ECC","slug":"program-exited-with-status","errorCode":null,"errorMessage":"{program} exited with {status}","messagePattern":"(.+?) exited with (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"ecc2/src/notifications.rs","lineNumber":395,"sourceCode":"            \"content\": message,\n            \"allowed_mentions\": {\n                \"parse\": []\n            }\n        }),\n    }\n}\n\n#[cfg(not(test))]\nfn run_notification_command(program: &str, args: &[String]) -> Result<()> {\n    let status = std::process::Command::new(program)\n        .args(args)\n        .status()\n        .with_context(|| format!(\"launch {program}\"))?;\n\n    if status.success() {\n        Ok(())\n    } else {\n        anyhow::bail!(\"{program} exited with {status}\");\n    }\n}\n\n#[cfg(test)]\nfn run_notification_command(_program: &str, _args: &[String]) -> Result<()> {\n    Ok(())\n}\n\n#[cfg(not(test))]\nfn send_webhook_request(target: &WebhookTarget, payload: serde_json::Value) -> Result<()> {\n    let agent = ureq::Agent::config_builder()\n        .timeout_connect(Some(std::time::Duration::from_secs(5)))\n        .timeout_recv_response(Some(std::time::Duration::from_secs(5)))\n        .build()\n        .new_agent();\n    let response = agent\n        .post(&target.url)\n        .send_json(payload)","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/notifications.rs#L377-L413","documentation":"Notification delivery runs an external command (the configured notification program) and checks its exit status. If the process launches but exits non-zero, this error surfaces the program name and its `ExitStatus` (e.g. ' exited with: exit status: 1'). It means the notification command itself failed, not that launching failed.","triggerScenarios":"The configured notification command exits non-zero — e.g. a script that prints to a closed pipe, `notify-send` unavailable via PATH inside the script, or a webhook-posting script receiving an HTTP error and exiting 1.","commonSituations":"Custom notification scripts with bugs; PATH differences when the daemon runs under systemd vs interactive shell; scripts failing when the desktop session/dbus is absent (headless server).","solutions":["Run the notification command manually with the same arguments to see its real error output.","Fix the exit path of the script so it returns 0 on success.","Check PATH and environment (dbus/display) for the process context; use absolute binary paths in the script.","Log stderr from the command; if notifications are optional, consider treating failure as non-fatal in the caller."],"exampleFix":"// before\n#!/bin/sh\nnotify-send \"$1\"   # fails on headless, exits 1\n// after\n#!/bin/sh\ncommand -v notify-send >/dev/null 2>&1 && notify-send \"$1\"\nexit 0","handlingStrategy":"try-catch","validationCode":"// before configuring, check the program exists\nif which::which(\"notify-send\").is_err() {\n    eprintln!(\"notification program not installed\");\n}","typeGuard":null,"tryCatchPattern":"match try_notify(&event) {\n    Err(e) if e.to_string().contains(\"exited with\") => {\n        log::warn!(\"notification command failed (non-fatal): {e}\");\n    }\n    Err(e) => log::error!(\"notify dispatch failed: {e}\"),\n    Ok(()) => {}\n}","preventionTips":["Make notification scripts exit 0 unless the failure is genuinely fatal.","Use absolute paths for binaries inside notification scripts.","Test notification commands in the same context (systemd/cron/headless) they will run in."],"tags":["notifications","process","subprocess","exit-status"],"backgroundTag":"command-not-found","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}