mvanhorn/last30days-skill · error · SourceRunError
All X backends failed — {last_error}
Error message
All X backends failed — {last_error} What it means
SourceRunError raised after the X backend chain is exhausted: every backend (bird, ScrapeCreators, grok, ...) either returned no items or errored, and at least one recorded an error (last_error). The failure state is classified — bird_x.classify_run_failure for 'bird:'-prefixed errors, otherwise http.classify_failure — so callers can distinguish auth, rate-limit, and network classes.
Source
Thrown at skills/last30days/scripts/lib/pipeline.py:4265
state = http.classify_failure(message=err)
return items, _outcome_artifact(
state,
f"X returned {len(items)} items but also errored: {err}",
)
# No auth issues and no prior errors - proceed to judge-retry
used_backend = backend
break
if err:
last_error = f"{backend}: {err}"
print(f"[X] backend '{backend}' failed ({err}); trying next", file=sys.stderr)
if not items and last_error:
state = (
bird_x.classify_run_failure(last_error)
if last_error.startswith("bird:")
else http.classify_failure(message=last_error)
)
raise SourceRunError(f"All X backends failed — {last_error}", state)
# Retrieve-judge-retry: judge corpus and retry if off-topic flood.
# Skip retry on quick/mock (same as Phase 2).
artifact = {}
if items and depth != "quick" and not mock:
items_for_judge = [
{"author_handle": it.get("author_handle", ""), "text": it.get("text", "")}
for it in items
]
if x_judge.should_retry_x_search(items_for_judge, x_query, ranking_query=ranking_query, depth=depth):
# Retry with cleaned query (1 retry, ≤2 extra grok calls)
# Strip noise words but preserve all significant terms to avoid
# losing disambiguating terms (e.g., "react server components")
core_tokens = query.extract_core_subject(x_query)
retry_query = core_tokens or x_query
print(f"[X] corpus off-topic; retrying with '{retry_query}'", file=sys.stderr)
if used_backend:View on GitHub (pinned to c7460f6114)
Solutions
- Read the error state: AUTH_FAILED → re-auth the failing backend (device flow / new key); RATE_LIMITED → back off and retry later.
- Verify the ScrapeCreators key with a minimal API call (check status code, never print the key).
- Pin a known-good backend at runtime (runtime.x_search_backend) to skip a broken primary.
- Retry the run after transient outages; if persistent, drop 'x' from sources to still get results elsewhere.
Example fix
# before
items, meta = fetch_x(subquery, ...)
# after
try:
items, meta = fetch_x(subquery, ...)
except SourceRunError as exc:
if "AUTH" in str(exc.state):
refresh_x_credentials()
items, meta = fetch_x(subquery, ...)
else:
raise Defensive patterns
Strategy: retry
Try / catch
try:
items, meta = fetch_x(...)
except SourceRunError as exc:
state = str(exc.state)
if "RATE" in state:
time.sleep(60)
items, meta = fetch_x(...)
elif "AUTH" in state:
refresh_x_credentials()
raise # caller must re-run with fixed credentials
else:
raise Prevention
- Keep more than one X backend configured (bird session + ScrapeCreators) so the chain has failover depth.
- Parse the trailing '<backend>: <err>' text to identify which backend died first.
- Rotate or refresh OAuth-backed backends (grok) on AUTH-classified failures instead of retrying.
When it happens
Trigger: Iterating the chain via _fetch_x_backend: each backend returns (items, err); a backend with items breaks the loop. If no backend yields items and last_error is non-empty (e.g. 'bird: token revoked' then 'scrapecreators: 429'), the SourceRunError is raised with the last error text.
Common situations: Revoked grok OAuth token plus exhausted ScrapeCreators quota; sustained rate limiting across all backends during heavy usage; upstream API outage; malformed query strings rejected by every backend.
Related errors
- Reddit primary and fallback produced no results after failur
- Reddit public search failed: {exc}
- Gemini HTTP {exc.code}: {detail}
- No X backend is available.
- Gemini request failed: {exc}
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/6284596085325094.
Report an issue: GitHub.