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
- Increase the timeout configured for the Mojeek fetch
- Check network connectivity/latency to mojeek.com
- Retry the search; Mojeek slowness is often transient
- 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
- Set timeouts generous enough for HTML scraping (10-20s)
- Pass an AbortSignal you actually control and check intent on abort
- Retry once on 504 before failing over to another provider
- Monitor latency to mojeek.com from your deployment environment
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- timed out: {command}
- AnthropicConnectionTimeoutError
- xAI device-code request failed: ${error instanceof Error ? e
- xAI device-code token polling failed: ${error instanceof Err
- options.firstItemErrorMessage ?? options.errorMessage
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e288bca7eba91b51.
Report an issue: GitHub.