mvanhorn/last30days-skill · error · ValueError
Unsupported web backend: {backend!r}
Error message
Unsupported web backend: {backend!r} What it means
Raised by grounding.py when the configured web_backend string matches none of the known backends (brave, exa, serper, parallel, keyless, none). This is a ValueError (invalid argument), not a missing-key RuntimeError — it fires before any key lookup and echoes the offending value via repr so whitespace and case errors are visible.
Source
Thrown at skills/last30days/scripts/lib/grounding.py:274
elif backend == "exa":
key = config.get("EXA_API_KEY")
if not key:
raise RuntimeError("EXA_API_KEY is required when web_backend='exa'")
items, artifact = exa_search(query, date_range, key)
elif backend == "serper":
key = config.get("SERPER_API_KEY")
if not key:
raise RuntimeError("SERPER_API_KEY is required when web_backend='serper'")
items, artifact = serper_search(query, date_range, key)
elif backend == "parallel":
key = config.get("PARALLEL_API_KEY")
if not key:
raise RuntimeError("PARALLEL_API_KEY is required when web_backend='parallel'")
items, artifact = parallel_search(query, date_range, key)
elif backend == "keyless":
items, artifact = web_search_keyless.keyless_search(query, date_range, config)
elif backend != "none":
raise ValueError(f"Unsupported web backend: {backend!r}")
else:
return [], {}
if items and not _reddit_excluded(config):
# Reddit enrichment is a best-effort secondary fetch on already-retrieved
# web results. Isolate its HTTP failures in a throwaway capture sink so a
# reddit.com fetch failure (e.g. a 403 on a datacenter IP) is not
# attributed to the web/grounding source itself — which would otherwise
# discard the successfully retrieved results and report the source failed.
with http.capture_failures():
items = _enrich_reddit_items(items)
return items, artifact
def _reddit_excluded(config: dict) -> bool:
"""Return True when EXCLUDE_SOURCES contains 'reddit'.
Respects the same suppression knob the pipeline uses for source gating,
so a user who set EXCLUDE_SOURCES=reddit doesn't get Reddit contentView on GitHub (pinned to c7460f6114)
Solutions
- Set web_backend to one of: brave, exa, serper, parallel, keyless, none.
- Strip whitespace/CR from the value (check for trailing newline when read from a file).
- Remove the setting entirely to use automatic resolution.
Example fix
# before WEB_BACKEND=brave-search # after WEB_BACKEND=brave
Defensive patterns
Strategy: validation
Validate before calling
ALLOWED_BACKENDS = {"brave", "exa", "serper", "parallel", "keyless", "none"}
backend = str(config.get("web_backend", "")).strip().lower()
assert backend in ALLOWED_BACKENDS, f"web_backend must be one of {sorted(ALLOWED_BACKENDS)}, got {backend!r}" Type guard
def is_valid_web_backend(value: object) -> bool:
return isinstance(value, str) and value.strip().lower() in {
"brave", "exa", "serper", "parallel", "keyless", "none"
} Try / catch
try:
grounding.web_search_with_backend(query, config)
except ValueError as e:
if 'Unsupported web backend' in str(e):
# normalize the value (strip().lower()) or unset it
... Prevention
- Normalize web_backend values with .strip().lower() at load time.
- Beware Windows line endings adding \r to values read from config files.
- After upgrading the engine, re-check the allowed backend list — names change between versions.
When it happens
Trigger: web_backend set to a typo ('bravesearch', 'Brave', 'googe'), a deprecated/renamed backend name after an upgrade, 'none ' with trailing whitespace or newline from a config file, or a value pasted from marketing copy ('web').
Common situations: Hand-editing .env or a YAML config; a harness passing --web-backend with a shell-quoted typo; version drift after a backend was renamed; values with trailing \r from Windows-edited files.
Related errors
- BRAVE_API_KEY is required when web_backend='brave'
- EXA_API_KEY is required when web_backend='exa'
- SERPER_API_KEY is required when web_backend='serper'
- PARALLEL_API_KEY is required when web_backend='parallel'
- Unknown search source in {flag_name}: {source}
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/90e461e861899523.
Report an issue: GitHub.