can1357/oh-my-pi · warning · SearchProviderError

Mojeek search timed out.

Error message

Mojeek search timed out.

What it means

Thrown by callMojeekHtml when the fetch to Mojeek's HTML results page fails and the abort signal is aborted — i.e. the operation exceeded its timeout (or the caller cancelled) after the underlying error was not already a SearchProviderError. It surfaces as a SearchProviderError with status 504 (gateway timeout semantics).

Source

Thrown at packages/coding-agent/src/web/search/providers/mojeek.ts:161

	try {
		page = await browserFetch(url, {
			fetch: params.fetch,
			signal,
			timeoutMs: params.timeoutMs,
			randomizeHeaders: false,
			referer: MOJEEK_HOME_URL,
			browser: {
				homeUrl: MOJEEK_HOME_URL,
				afterNavigation: solveCaptcha,
				shouldFallback: isRobotPage,
				attempts: 2,
				retryDelayMs: 1_000,
			},
		});
	} catch (error) {
		if (error instanceof SearchProviderError || params.signal?.aborted) throw error;
		if (signal.aborted) {
			throw new SearchProviderError("mojeek", "Mojeek search timed out.", 504);
		}
		const message = error instanceof Error ? error.message : String(error);
		throw new SearchProviderError("mojeek", `Mojeek search failed: ${message}`, 503);
	}

	// Robot walls: the ALTCHA proof-of-work captcha page arrives as HTTP 200
	// (`<title>Captcha</title>`, `altcha-widget`) and the "automated queries"
	// refusal as HTTP 403. Both bodies are more actionable than their raw
	// statuses, so check them before the generic status handling.
	if (isRobotPage(page)) {
		throw new SearchProviderError(
			"mojeek",
			"Mojeek blocked the request with its automated-queries wall. Mojeek rate-limits scripted searches from datacenter/shared-egress IPs; retry later or configure another provider such as Brave, Tavily, Exa, or Kagi.",
			429,
		);
	}
	if (page.status < 200 || page.status >= 300) {
		const classified = classifyProviderHttpError("mojeek", page.status, page.html);

View on GitHub (pinned to 9690622007)

Solutions

  1. Increase the timeout configured for the Mojeek fetch
  2. Check network connectivity/latency to mojeek.com
  3. Retry the search; Mojeek slowness is often transient
  4. Respect the abort signal — if cancellation was intentional, propagate rather than retry

Example fix

// before
callMojeekHtml(params) // default timeout too tight
// after
callMojeekHtml({ ...params, timeoutMs: 15_000 })
Defensive patterns

Strategy: retry

Validate before calling

// ensure a sane timeout is configured upstream
const timeoutMs = params.timeoutMs ?? 15_000;

Try / catch

try {
  const res = await searchMojeek({ query, signal });
} catch (err) {
  if (err instanceof SearchProviderError && err.status === 504) {
    // timeout: retry once with a longer timeout or fall back
  } else throw err;
}

Prevention

When it happens

Trigger: Mojeek fetch exceeds the configured timeout (retryDelayMs/timeout settings around the fetchWithRetry call) or the caller's signal aborts mid-flight, with no SearchProviderError already raised.

Common situations: Slow or congested network to mojeek.com; Mojeek slow to respond under load; overly tight timeout configuration; user cancels the search.

Understand the failure class

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/e288bca7eba91b51. Report an issue: GitHub.