Skip to content

fix(search): fall back to duckduckgo-free when no search provider is configured - #11097

Merged
diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.50from
Egorich-print:fix/search-free-fallback
Aug 23, 2026
Merged

diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.50from
Egorich-print:fix/search-free-fallback

Conversation

@Egorich-print

Copy link
Copy Markdown
Contributor

Problem

Out of the box (zero search provider credentials configured), POST /v1/search always failed with:

OmniRoute API error [400]: {"error":{"message":"No credentials configured for any search provider. Add an API key for a search provider (serper-search, brave-search, ...) in the dashboard.","type":"invalid_request_error","code":"bad_request"}}

even though the registry ships a free no-key provider (duckduckgo-free) exactly for this case.

Root cause

In the auto-select path of src/app/api/v1/search/route.ts, fallback-only providers (duckduckgo-free, searxng-search) were only ever promoted to the alternate slot (the last-resort failover block). When no credentialed provider was found, the 400 error was returned before that block could run — so the last-resort path was dead code in the zero-credentials case.

The lib variant src/lib/search/executeWebSearch.ts already handles this correctly (it promotes duckduckgo-free with empty credentials), so the two paths disagreed.

Fix

Promote a fallback-only provider to the primary pick as a last resort before failing, mirroring executeWebSearch():

  • duckduckgo-free runs with empty credentials (HTML scraping path, no key needed)
  • searxng-search is used only when it has explicitly configured credentials
  • honors blockedProviders and rate-limit state like the rest of the selection logic

…configured

POST /v1/search returned 400 'No credentials configured for any search
provider' out of the box because the auto-select path only ever promoted
fallback-only providers (duckduckgo-free, searxng-search) to the alternate
slot, never to the primary one. When no paid provider had credentials the
error was returned before the last-resort alternate step could run.

Promote a fallback-only provider to primary as a last resort before failing,
mirroring executeWebSearch(): duckduckgo-free runs with empty credentials,
searxng-search only when explicitly configured, honoring blockedProviders.
The Dark Reader browser extension injects data-darkreader-* attributes and
--darkreader-* CSS variables into SVG elements after React hydration,
causing a hydration mismatch warning. Adding suppressHydrationWarning to
the root SVG element is the standard React pattern to suppress this
browser-extension-induced hydration mismatch.

Fixes: Console warning about mismatched data-darkreader-inline-stroke
and --darkreader-inline-stroke attributes on OmniRouteLogo lines.
@diegosouzapw
diegosouzapw merged commit 0b41259 into cheaper-inference:release/v3.8.50 Aug 23, 2026
9 of 16 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…configured (cheaper-inference#11097)

Validated on the combined batch board over tip 76f9b2f: static gates clean (changelog, file-size 159 frozen, complexity 2621<=2774, cognitive 1181<=1223, dead-code 408<=416), typecheck:core clean, 107 focused tests green.

Zero-credential /v1/search now actually reaches the fallback-only providers (duckduckgo-free/searxng) instead of erroring before the last-resort block could run — the dead-code path is live. Also carries a one-line suppressHydrationWarning on the logo. Thank you @Egorich-print!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants