tonhowtf/omniget · error

{} falhou: {}

Error message

{} falhou: {}

What it means

This generic helper in startup.rs runs an external command (osascript on macOS, gsettings/systemctl etc. on Linux) and fails with "<program> falhou: <stderr>" when the process exits with a non-zero status. The command's stderr is trimmed and embedded in the message. It is the single choke point through which all login-items operations (mac_items, mac_set, linux_items, linux_set) report subprocess failures.

Solutions

  1. Read the stderr text embedded in the error message; it names the underlying cause (permission denied, command not found, no such item)
  2. On macOS, grant the app Automation permission for System Events in System Settings > Privacy & Security > Automation (or re-sign with proper entitlements)
  3. On Linux, ensure the app runs inside the user's graphical session with D-Bus available (DBUS_SESSION_BUS_ADDRESS set)
  4. Verify the required binaries (osascript, gsettings, systemctl) exist and are on PATH for the environment running the app
  5. Quote/escape item names passed into AppleScript and confirm the login item actually exists before removing it

Example fix

// before: opaque failure when binary is missing or stderr is empty
let o = crate::core::process::command(program).args(args).output().await?;
if !o.status.success() {
    return Err(anyhow!("{} falhou: {}", program, String::from_utf8_lossy(&o.stderr).trim()));
}
// after: distinguish spawn failure from non-zero exit
let o = crate::core::process::command(program).args(args).output().await
    .with_context(|| format!("nao foi possivel executar '{}'", program))?;
if !o.status.success() {
    let err = String::from_utf8_lossy(&o.stderr).trim();
    let out = String::from_utf8_lossy(&o.stdout).trim();
    return Err(anyhow!("{} falhou ({}): {}{}", program, o.status, err,
        if err.is_empty() { out } else { "" }));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the external tool is available before using it
async fn tool_available(program: &str) -> bool {
    crate::core::process::command(program).arg("--help")
        .output().await.map(|o| o.status.success()).unwrap_or(false)
}
if !tool_available("osascript").await { return Err(anyhow!("osascript indisponivel neste ambiente")); }

Type guard

fn has_usable_stderr(o: &std::process::Output) -> bool {
    !String::from_utf8_lossy(&o.stderr).trim().is_empty()
}

Try / catch

match set_enabled(item, true).await {
    Ok(_) => {},
    Err(e) if e.to_string().contains("osascript falhou") => {
        eprintln!("Conceda permissao de Automacao (System Events) ao app: {e}");
    }
    Err(e) if e.to_string().contains("gsettings falhou") => {
        eprintln!("Execute dentro de uma sessao grafica com D-Bus: {e}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any startup-items operation where the spawned process exits non-zero: osascript lacks Automation/Accessibility permission to control System Events, the binary does not exist or is not on PATH, gsettings fails because DBUS_SESSION_BUS_ADDRESS is unset (e.g. running outside the user session), or the requested login item does not exist for a remove query.

Common situations: macOS Tauri app not granted 'Automation' permission for System Events so osascript returns error 1002 or -1743; running the app from SSH/cron with no D-Bus session on Linux; missing osascript/gsettings binaries in a minimal container; AppleScript syntax rejected due to an item name containing quotes.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/3c0436b1bdb515b4. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/startup.rs:36

    pub source: String,
    /// "user" | "system"
    pub scope: String,
    pub path: String,
    pub enabled: bool,
    pub can_toggle: bool,
}

fn home() -> PathBuf {
    dirs::home_dir().unwrap_or_default()
}

async fn run(program: &str, args: &[&str]) -> anyhow::Result<String> {
    let o = crate::core::process::command(program)
        .args(args)
        .output()
        .await?;
    if !o.status.success() {
        return Err(anyhow!(
            "{} falhou: {}",
            program,
            String::from_utf8_lossy(&o.stderr).trim()
        ));
    }
    Ok(String::from_utf8_lossy(&o.stdout).to_string())
}

// ── macOS ──────────────────────────────────────────────────────────────

async fn plist_json(path: &Path) -> Option<serde_json::Value> {
    let o = crate::core::process::command("plutil")
        .args(["-convert", "json", "-o", "-"])
        .arg(path)
        .output()
        .await
        .ok()?;
    if !o.status.success() {

View on GitHub (pinned to 8600b91f42)