nexu-io/open-design · error · RuntimeError

No sources are available for this run.

Error message

No sources are available for this run.

What it means

pipeline.run() computes the effective source list `available` from available_sources(config, requested_sources), filters it by requested_sources, drops 'grounding' when web_backend == 'none' (or adds it when a web backend is active), and then asserts `if not available: raise RuntimeError("No sources are available for this run.")`. In mock mode, available defaults to MOCK_AVAILABLE_SOURCES (or requested_sources), so this normally only fires on real runs where no source could be enabled — i.e. no provider keys, no X/Threads/etc. credentials, and the request filtered everything out.

Source

Thrown at design-templates/last30days/scripts/lib/pipeline.py:202

    settings = DEPTH_SETTINGS[depth]
    requested_sources = normalize_requested_sources(requested_sources)
    from_date, to_date = dates.get_date_range(lookback_days)

    if mock:
        runtime = providers.mock_runtime(config, depth)
        reasoning_provider = None
        available = list(requested_sources or MOCK_AVAILABLE_SOURCES)
    else:
        runtime, reasoning_provider = providers.resolve_runtime(config, depth)
        available = available_sources(config, requested_sources)
        if requested_sources:
            available = [source for source in available if source in requested_sources]
    if web_backend == "none":
        available = [s for s in available if s != "grounding"]
    elif web_backend in ("brave", "exa", "serper") and "grounding" not in available:
        available.append("grounding")
    if not available:
        raise RuntimeError("No sources are available for this run.")

    if external_plan:
        # External plan provided (e.g., from Claude Code via --plan flag).
        # Parse it through the same sanitizer to validate structure.
        plan = planner._sanitize_plan(
            external_plan, topic, available, requested_sources, depth,
        )
        plan_source = "external"
    else:
        plan = planner.plan_query(
            topic=topic,
            available_sources=available,
            requested_sources=requested_sources,
            depth=depth,
            provider=None if mock else reasoning_provider,
            model=None if mock else runtime.planner_model,
            context=config.get("_auto_resolve_context", ""),
            internal_subrun=internal_subrun,

View on GitHub (pinned to 5be4028344)

Solutions

  1. Run `last30days ... --diagnose` (or inspect pipeline.diagnose output) to see which sources are available and why.
  2. Set at least one provider key (OPENAI_API_KEY / XAI_API_KEY / OPENROUTER_API_KEY) and/or a web backend key (BRAVE/EXA/SERPER/PARALLEL).
  3. Re-authenticate the X source (bird) if `--search x` is required.
  4. Drop the offending `--search` filter, or do not combine `--web-backend none` with `--search grounding`.
  5. Use `--mock` for an offline run that does not require credentials.

Example fix

# before (no keys, grounding-only, web off)
python3.12 last30days.py --topic x --web-backend none --search grounding
# after
export OPENAI_API_KEY=sk-...
python3.12 last30days.py --topic x --web-backend auto
Defensive patterns

Strategy: validation

Validate before calling

from lib import pipeline
diag = pipeline.diagnose(config, requested_sources)
available = diag['available_sources']
if not available:
    raise RuntimeError(f'no sources available with current config: providers={diag["providers"]}, x_backend={diag["x_backend"]}')

Try / catch

try:
    report = pipeline.run(topic=t, config=config, depth=depth, requested_sources=src, web_backend=wb)
except RuntimeError as e:
    if 'No sources are available' in str(e):
        # surface diagnose() to the user and/or retry with --mock
        print(pipeline.diagnose(config, src))
    raise

Prevention

When it happens

Trigger: Real (non-mock) run with no API keys/credentials of any kind AND `--search` restricts to sources that all need credentials; or `--search X` where X is never available in this env; or web_backend='none' combined with `--search grounding` (grounding is then removed, leaving an empty list).

Common situations: First run with no env configured; revoked/expired X (bird) session; OPENAI/OPENROUTER/XAI keys removed and `--search` restricted to x only; CI without secrets; explicitly passing `--web-backend none --search grounding`.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/a7d39cf1cad70d32. Report an issue: GitHub.