tonhowtf/omniget · error · anyhow::Error

thread

Error message

thread: {}

What it means

start() spawns the autoclicker worker thread and propagates a failure from thread::Builder::spawn via anyhow!("thread: {}", e). The OS refused to create the thread (typically resource exhaustion), and the library resets RUNNING to false before returning this error.

Solutions

  1. Audit the app for leaked threads/loops that spawn per operation without joining or exiting.
  2. Raise the thread limit (ulimit -u on Linux) or process memory allowance in constrained environments.
  3. Handle the error by informing the user the autoclicker couldn't start due to OS resource limits, since RUNNING was already reset.
  4. Consider reusing a single long-lived worker thread controlled by flags instead of spawning per start().

Example fix

// before
thread::Builder::new().name("autoclick".into()).spawn(move || { ... })
    .map_err(|e| { RUNNING.store(false, Ordering::SeqCst); anyhow!("thread: {}", e) })?;
// after
// reuse a persistent worker; only fail when spawn truly fails:
match worker_handle() {
    Some(h) => { h.signal_start(opts); Ok(()) }
    None => Err(anyhow!("sem recursos para iniciar o autoclicker: verifique limites do sistema")),
}
Defensive patterns

Strategy: try-catch

Validate before calling

// heurística: limite de threads do processo
fn near_thread_limit() -> bool {
    std::fs::read_to_string("/proc/self/status")
        .map(|s| s.lines().any(|l| l.starts_with("Threads:")))
        .unwrap_or(false)
}

Try / catch

match autoclick::start(opts) {
    Err(e) if e.to_string().starts_with("thread:") =>
        show_error("SO recusou a criação da thread: verifique memória/limites (ulimit)"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling start() when thread spawn fails — usually std::io::Error from the OS: out of memory, per-process or system thread limit reached (RLIMIT/ulimit), or resource unavailability.

Common situations: App leaked many threads so the process hit its thread cap; low-memory environments/containers with tight cgroup limits; extremely low ulimit -u on Linux; running thousands of instances of the tool.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/autoclick.rs:188

                rng_state ^= rng_state >> 7;
                rng_state ^= rng_state << 17;
                let jitter = if opts.jitter_pct > 0 {
                    let pct = (rng_state % (2 * opts.jitter_pct as u64 + 1)) as f64 - opts.jitter_pct as f64;
                    1.0 + pct / 100.0
                } else {
                    1.0
                };
                next += base.mul_f64(jitter.max(0.05));
                if next < Instant::now() {
                    next = Instant::now();
                }
                sleep_until(next);
            }
            RUNNING.store(false, Ordering::SeqCst);
        })
        .map_err(|e| {
            RUNNING.store(false, Ordering::SeqCst);
            anyhow!("thread: {}", e)
        })?;
    Ok(())
}

pub fn stop() {
    RUNNING.store(false, Ordering::SeqCst);
}

/// Atalho global: para se estiver rodando, senão começa com as últimas opções.
pub fn toggle() -> anyhow::Result<bool> {
    if RUNNING.load(Ordering::SeqCst) {
        stop();
        return Ok(false);
    }
    let opts = last_options()
        .ok_or_else(|| anyhow!("configure e inicie uma vez pela tela antes de usar o atalho"))?;
    start(opts)?;
    Ok(true)

View on GitHub (pinned to 8600b91f42)