can1357/oh-my-pi · warning · SearchProviderError
Ecosia blocked the request with a Cloudflare bot challenge.
Error message
Ecosia blocked the request with a Cloudflare bot challenge. Ecosia's firewall throttles automated searches from datacenter/shared-egress IPs; try another web search provider such as DuckDuckGo, Brave, or Tavily.
What it means
Ecosia served a page containing a Cloudflare bot challenge instead of search results. The provider detects this (isBlockedPage) and raises HTTP 429. Ecosia's firewall throttles automated searches coming from datacenter or shared-egress IPs, so requests from servers/VPNs/CI runners are frequently challenged.
Source
Thrown at packages/coding-agent/src/web/search/providers/ecosia.ts:135
homeUrl: ECOSIA_HOME_URL,
ready: {
selector: 'article[data-test-id="organic-result"]',
timeoutMs: RESULT_RENDER_TIMEOUT_MS,
},
shouldFallback: isBlockedPage,
},
});
} catch (error) {
if (error instanceof SearchProviderError || params.signal?.aborted) throw error;
if (signal.aborted) {
throw new SearchProviderError("ecosia", "Ecosia search timed out.", 504);
}
const message = error instanceof Error ? error.message : String(error);
throw new SearchProviderError("ecosia", `Ecosia search failed: ${message}`, 503);
}
if (isBlockedPage(page)) {
throw new SearchProviderError(
"ecosia",
"Ecosia blocked the request with a Cloudflare bot challenge. Ecosia's firewall throttles automated searches from datacenter/shared-egress IPs; try another web search provider such as DuckDuckGo, Brave, or Tavily.",
429,
);
}
if (page.status < 200 || page.status >= 300) {
const classified = classifyProviderHttpError("ecosia", page.status, page.html);
if (classified) throw classified;
throw new SearchProviderError("ecosia", `Ecosia HTML error (${page.status})`, page.status);
}
return page.html;
}
/** Execute an Ecosia web search and parse the server-rendered result page. */
export async function searchEcosia(params: SearchParams): Promise<SearchResponse> {
const numResults = clampNumResults(params.numSearchResults ?? params.limit, DEFAULT_NUM_RESULTS, MAX_NUM_RESULTS);
const html = await callEcosiaHtml(params);
const parsed = parseHtmlResults(html);View on GitHub (pinned to 9690622007)
Solutions
- Configure a different web search provider (DuckDuckGo, Brave, or Tavily) via an API key — these are the explicitly recommended alternatives.
- Run from a residential/different network IP if Ecosia must be used.
- Reduce Ecosia query rate to avoid triggering throttling.
- Check for an Ecosia API integration or paid search API instead of HTML scraping.
Example fix
// before
const results = await search({ provider: "ecosia", query });
// after
const results = await search({ provider: "brave", query }); // with BRAVE_API_KEY set Defensive patterns
Strategy: fallback
Validate before calling
const res = await fetch("https://www.ecosia.org/search?q=test");
const html = await res.text();
const likelyBlocked = html.includes("cf-challenge") || html.includes("Just a moment...");
if (likelyBlocked) console.warn("Ecosia will challenge this IP; use another provider"); Try / catch
try {
const res = await search({ provider: "ecosia", query });
} catch (e) {
if (e instanceof SearchProviderError && e.status === 429) {
const res = await search({ provider: "duckduckgo", query }); // recommended fallback
} else throw e;
} Prevention
- Configure an API-key provider (Brave, Tavily, DuckDuckGo) for datacenter/CI environments
- Avoid running Ecosia scrapes from shared cloud egress IPs
- Throttle query rate to stay below challenge thresholds
- Treat 429 from this provider as permanent for the current IP, not retryable
When it happens
Trigger: callEcosiaHtml fetched a 200-class HTML page but isBlockedPage(page) matched Cloudflare challenge markers in the markup. Typical when running from cloud VMs, containers, VPNs, or after many rapid automated queries from one IP.
Common situations: Running the coding agent on an AWS/GCP/Azure box; corporate shared NAT egress; scraping Ecosia at high volume; Ecosia tightening bot protection after a markup change.
Related errors
- DuckDuckGo blocked the request with a bot-detection challeng
- DuckDuckGo HTML error (${page.status})
- Ecosia search timed out.
- Ecosia search failed: ${message}
- Ecosia HTML error (${page.status})
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b7bb4ab0f61f9ce7.
Report an issue: GitHub.