lbjlaq/Antigravity-Manager · error

brew_timeout

brew_timeout

Error message

brew_timeout

What it means

brew_upgrade_cask (src-tauri/src/modules/update_checker.rs) wraps the `brew upgrade --cask antigravity-tools` invocation in tokio::time::timeout with a 180-second budget. 'brew_timeout' is returned when the elapsed-time future resolves first, i.e. brew did not finish within 3 minutes and the child future is dropped. This is a safety guard so the UI does not hang forever on a stalled brew process.

Solutions

  1. Run `brew upgrade --cask antigravity-tools` manually in Terminal to see where it stalls and let it finish once; then retry the in-app upgrade (subsequent runs are usually faster since downloads are cached).
  2. Ensure no other brew process is running (`pgrep -fl brew`) that could hold the Homebrew lock; wait or kill stale processes.
  3. Pre-warm with `brew update` beforehand so the upgrade command skips the slow tap-update phase inside the 3-minute window.
  4. Check network/proxy speed to the cask download URL; use a faster connection or VPN off, then retry.
  5. If timeouts are chronic in your environment, run the upgrade manually and use the app after; the 3-minute timeout is hardcoded in update_checker.rs:510-516.

Example fix

// before: upgrade blocked by concurrent brew holding the lock, hits 180s timeout
// terminal:
pgrep -fl brew                          // finds stale brew process
kill <stale_pid>
brew update && brew upgrade --cask antigravity-tools   // completes < 3 min
// after: retry upgrade in app -> succeeds
Defensive patterns

Strategy: retry

Validate before calling

// Check for a concurrent brew process / lock before triggering the in-app upgrade
const { exec } = require('child_process');
exec('pgrep -fl brew', (err, stdout) => {
  if (stdout && stdout.trim()) console.warn('another brew process is running; upgrade may time out');
});

Try / catch

let ok = false;
for (let i = 0; i < 2 && !ok; i++) {
  try { await invoke('brew_upgrade_cask'); ok = true; }
  catch (e) {
    if (e !== 'brew_timeout') throw e;
    showHint('brew is slow (network/lock). Ensure no other brew run is active, then retry.');
  }
}

Prevention

When it happens

Trigger: tokio::time::timeout(Duration::from_secs(180), brew_command.output()) returns Err — brew ran longer than 3 minutes, typically because it was updating itself/other casks, downloading slowly, prompting, waiting on a lock, or hung on network access to formulae.brew.sh or the cask download host.

Common situations: Slow or proxied internet making the cask download exceed 3 minutes; concurrent brew operations holding the Homebrew lock (another Terminal brew run); brew auto-updating its own tap first (`brew update` phase); a stuck sudo/prompt-less network credential dialog; heavily loaded CI/VM.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of lbjlaq/Antigravity-Manager@90a2b6b207 (2026-09-19). Data as JSON: /api/errors/5801483defedd6de. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/modules/update_checker.rs:526

    // 3 min timeout to prevent hanging
    let result = tokio::time::timeout(
        std::time::Duration::from_secs(180),
        tokio::process::Command::new(brew_path)
            .args(["upgrade", "--cask", "antigravity-tools"])
            .output(),
    )
    .await;

    let output = match result {
        Ok(Ok(output)) => output,
        Ok(Err(e)) => {
            logger::log_error(&format!("Failed to execute brew upgrade: {}", e));
            return Err("brew_exec_failed".to_string());
        }
        Err(_) => {
            logger::log_error("Homebrew upgrade timed out after 3 minutes");
            return Err("brew_timeout".to_string());
        }
    };

    let stdout = String::from_utf8_lossy(&output.stdout).to_string();
    let stderr = String::from_utf8_lossy(&output.stderr).to_string();

    if output.status.success() {
        logger::log_info(&format!("Homebrew upgrade succeeded: {}", stdout));
        Ok(stdout)
    } else {
        logger::log_error(&format!(
            "brew upgrade failed - stdout: {} stderr: {}",
            stdout, stderr
        ));
        // Return structured error key for frontend i18n
        if stderr.contains("already installed") || stdout.contains("already installed") {
            Err("brew_already_latest".to_string())
        } else {

View on GitHub (pinned to 90a2b6b207)