mvanhorn/last30days-skill · error · ValueError
Discovery supports listing sources only: reddit…
Error message
Discovery supports listing sources only: reddit, hackernews, digg (unsupported: {', '.join(unsupported)}) What it means
Thrown by the shared discovery-sweep prologue in pipeline.py when the caller passes requested sources that are not listing sources. Discovery (run_discover / run_discover_nominate) only sweeps feed-style listing sources — reddit, hackernews, digg — because it works by listing recent feeds, not by keyword search. Any other source name (e.g. 'x', 'youtube', 'bluesky') is rejected up front before any network call.
Solutions
- Restrict requested_sources for discovery calls to subsets of ['reddit', 'hackernews', 'digg'].
- If you want X/YouTube content, use the main research pipeline (run_pipeline), not discovery — discovery only nominates topics from listing feeds.
- Filter the offending names before calling: [s for s in requested if s in {'reddit','hackernews','digg'}].
- Check for typos/casing in the source names (normalize_requested_sources handles aliases, but non-existent sources still fail).
Example fix
# before plan = run_discover(domain="ai agents", requested_sources=["reddit", "x", "youtube"]) # after plan = run_discover(domain="ai agents", requested_sources=["reddit", "hackernews", "digg"])
Defensive patterns
Strategy: validation
Validate before calling
DISCOVERY_SOURCES = {"reddit", "hackernews", "digg"}
requested = ["reddit", "x"]
bad = set(requested) - DISCOVERY_SOURCES
if bad:
raise SystemExit(f"not valid for discovery: {sorted(bad)}")
requested = [s for s in requested if s in DISCOVERY_SOURCES] or list(DISCOVERY_SOURCES) Type guard
def is_discovery_source_list(sources: list[str]) -> bool:
return bool(sources) and all(s in {"reddit", "hackernews", "digg"} for s in sources) Try / catch
try:
sweep = run_discover(domain, requested_sources=clean)
except ValueError as exc:
if "unsupported" in str(exc):
clean = [s for s in clean if s in DISCOVERY_SOURCES]
sweep = run_discover(domain, requested_sources=clean)
else:
raise Prevention
- Keep a module-level DISCOVERY_SOURCES constant and validate against it before every discovery call.
- Never forward main-pipeline source lists (which include x/youtube/etc.) into discovery unfiltered.
When it happens
Trigger: Calling run_discover / run_discover_nominate (or the CLI discover path) with requested_sources containing names outside DISCOVERY_SOURCES, e.g. ['reddit', 'x'] or ['youtube']. The set difference of requested minus {reddit, hackernews, digg} is non-empty after normalize_requested_sources().
Common situations: Reusing a research-run source list (--sources reddit,x,youtube) for a discovery run; assuming discovery accepts the same source vocabulary as the main pipeline; typos in source names; a harness passing INCLUDE_SOURCES-style env values into discovery.
Related errors
- No listing sources are available for global trending
- No listing sources are available for
- requires at least one source.
- subqueries[ ].sources must be a non-empty string array
- Unknown search source in
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/10a8779cbbb35630.
Report an issue: GitHub.
Appendix: source
Thrown at skills/last30days/scripts/lib/pipeline.py:1062
config: dict[str, Any],
depth: str,
requested_sources: list[str] | None,
mock: bool,
subreddits: list[str] | None,
lookback_days: int,
as_of_date: str | None,
) -> _DiscoverySweep:
"""Resolve the momentum window, validate/bound the listing sources, build
the discovery plan, sweep the river feeds, and finalize source status.
Shared verbatim by ``run_discover`` (one-shot) and
``run_discover_nominate`` (protocol leg 1) so the two paths can never
drift on what a sweep means."""
from_date, to_date = dates.get_date_range(lookback_days, as_of_date=as_of_date)
requested = normalize_requested_sources(requested_sources)
unsupported = sorted(set(requested or []) - set(DISCOVERY_SOURCES))
if unsupported:
raise ValueError(
"Discovery supports listing sources only: reddit, hackernews, digg "
f"(unsupported: {', '.join(unsupported)})"
)
available = list(DISCOVERY_SOURCES) if mock else [
source for source in available_sources(config, requested, x_pending=False)
if source in DISCOVERY_SOURCES
]
if requested:
available = [source for source in available if source in requested]
plan = planner.build_discovery_plan(
domain,
available_sources=available,
subreddits=subreddits,
)
global_mode = not plan.domain
domain_label = plan.domain or "everything"
query_plan = schema.QueryPlan(View on GitHub (pinned to c7460f6114)