tonhowtf/omniget · error · anyhow::Error

caminho do item de login desconhecido

Error message

caminho do item de login desconhecido

What it means

In mac_set, when disabling a login item the code first removes the existing login item and then re-adds it with the same path. To re-add it, it looks up the item's path either from the 'removed' list recorded earlier in the call or from item.path; if both are empty it cannot reconstruct the path and throws this error instead of creating a login item with an invalid empty path.

Solutions

  1. Ensure items returned by mac_items always populate 'path' (resolve via System Events properties or the app bundle path) before allowing enable/disable in the UI
  2. Refresh the item list immediately before calling set_enabled so names/paths are in sync
  3. When path is empty, re-enumerate login items via osascript to recover the real path instead of failing
  4. Skip or warn on items without a resolvable path rather than attempting the remove/re-add cycle
  5. Persist the resolved path with each item so later set_enabled calls always have it

Example fix

// before
let path = removed.iter().find(|(n, _)| *n == item.name)
    .map(|(_, p)| p.clone())
    .unwrap_or_else(|| item.path.clone());
if path.is_empty() {
    return Err(anyhow!("caminho do item de login desconhecido"));
}
// after: recover the path from a fresh System Events query before failing
let path = removed.iter().find(|(n, _)| *n == item.name)
    .map(|(_, p)| p.clone())
    .filter(|p| !p.is_empty())
    .or_else(|| item.path.clone().into_option_if_non_empty())
    .or_else(|| resolve_login_item_path(&item.name));
let Some(path) = path else {
    return Err(anyhow!("caminho do item de login desconhecido para '{}'", item.name));
};
Defensive patterns

Strategy: validation

Validate before calling

// Refuse to toggle items without a resolvable path
fn can_toggle(item: &StartupItem) -> bool {
    !item.name.is_empty() && !item.path.is_empty()
}
if !can_toggle(&item) {
    // resolve or re-enumerate before calling set_enabled
    item = refresh_item_path(item)?;
}

Type guard

fn has_resolvable_path(item: &StartupItem) -> bool {
    !item.path.trim().is_empty()
}

Try / catch

match set_enabled(item, false).await {
    Ok(_) => refresh_items(),
    Err(e) if e.to_string().contains("caminho do item de login desconhecido") => {
        // re-enumerate login items to recover the path, then retry once
        let items = mac_items().await?;
        set_enabled(items.iter().find(|i| i.name == item.name).unwrap(), false).await?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling set_enabled(item, false) for a macOS login-item whose 'path' field is empty and whose name does not match any entry captured in the removed list — e.g. an item enumerated with a blank path, or a name that changed between listing and the disable call.

Common situations: Startup items discovered via System Events that report only a name (no resolved path); stale UI state where the item list was refreshed and names no longer match; items added by the app bundle whose path metadata was never persisted; corrupt/legacy persisted startup-item records with empty paths.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

                .await;
                run(
                    "launchctl",
                    &["disable", &format!("{}/{}", target, item.name)],
                )
                .await?;
            }
            Ok(())
        }
        "login-item" => {
            let mut removed = removed_login_items();
            if enabled {
                let path = removed
                    .iter()
                    .find(|(n, _)| *n == item.name)
                    .map(|(_, p)| p.clone())
                    .unwrap_or_else(|| item.path.clone());
                if path.is_empty() {
                    return Err(anyhow!("caminho do item de login desconhecido"));
                }
                run("osascript", &["-e", &format!("tell application \"System Events\" to make login item at end with properties {{path:\"{}\", hidden:false}}", path.replace('"', "\\\""))]).await?;
                removed.retain(|(n, _)| *n != item.name);
            } else {
                run(
                    "osascript",
                    &[
                        "-e",
                        &format!(
                            "tell application \"System Events\" to delete login item \"{}\"",
                            item.name.replace('"', "\\\"")
                        ),
                    ],
                )
                .await?;
                removed.retain(|(n, _)| *n != item.name);
                removed.push((item.name.clone(), item.path.clone()));
            }

View on GitHub (pinned to 8600b91f42)