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
- Read the stderr text embedded in the error message; it names the underlying cause (permission denied, command not found, no such item)
- On macOS, grant the app Automation permission for System Events in System Settings > Privacy & Security > Automation (or re-sign with proper entitlements)
- On Linux, ensure the app runs inside the user's graphical session with D-Bus available (DBUS_SESSION_BUS_ADDRESS set)
- Verify the required binaries (osascript, gsettings, systemctl) exist and are on PATH for the environment running the app
- 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
- Grant macOS Automation permission for System Events on first launch (and ship entitlements)
- Run Linux startup-item operations inside the user's graphical session with D-Bus present
- Check tool availability on PATH at app startup and degrade gracefully
- Include both stderr and exit status in subprocess errors for diagnosability
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)