mvanhorn/last30days-skill · error · ValueError

No listing sources are available for global trending

Error message

No listing sources are available for global trending

What it means

ValueError from planner.build_discovery_plan in the GLOBAL trending branch (empty/whitespace domain). After discarding 'x' from the allowed set, it intersects DISCOVERY_SOURCE_ORDER with the allowed sources; if nothing survives, there is no listing source to sweep and discovery cannot proceed. Note this branch explicitly drops 'x' even if the caller allowed it.

Source

Thrown at skills/last30days/scripts/lib/planner.py:48

    An empty domain is global trending: sweep every river feed's own hot list
    (r/all, HN front page, Digg) with no category scoping. Keyword-driven
    sources (X, Techmeme, arXiv - none of which expose a river/front-page
    lane) sit out of the global nominate stage and join per-topic at the
    enrichment pass, where every nomination gets a full research run.
    """
    normalized_domain = " ".join(domain.split())
    if not normalized_domain:
        resolved = [
            subreddit.removeprefix("r/").strip()
            for subreddit in (subreddits or ["all"])
            if subreddit.strip()
        ]
        allowed = set(DISCOVERY_SOURCE_ORDER if available_sources is None else available_sources)
        allowed.discard("x")
        sources = [source for source in DISCOVERY_SOURCE_ORDER if source in allowed]
        if not sources:
            raise ValueError("No listing sources are available for global trending")
        return schema.DiscoveryPlan(
            domain="",
            category=None,
            subreddits=resolved or ["all"],
            sources=sources,
        )

    category = categories.detect_category(normalized_domain)
    candidate_subreddits = list(subreddits or categories.peer_subs_for(category))
    seen_subreddits: set[str] = set()
    resolved_subreddits: list[str] = []
    for subreddit in candidate_subreddits:
        normalized_subreddit = subreddit.removeprefix("r/").strip()
        key = normalized_subreddit.lower()
        if not normalized_subreddit or key in seen_subreddits:
            continue
        seen_subreddits.add(key)
        resolved_subreddits.append(normalized_subreddit)

View on GitHub (pinned to c7460f6114)

Solutions

  1. Include at least one of reddit/hackernews/digg in available_sources when calling build_discovery_plan for global trending.
  2. Prefer the pipeline entry points (run_discover) which pre-filter available sources and raise the earlier, clearer error instead.
  3. If you truly have no listing sources, fix availability first (all three are keyless-capable).

Example fix

# before
plan = planner.build_discovery_plan("", available_sources=["x"])

# after
plan = planner.build_discovery_plan("", available_sources=["reddit", "hackernews"])
Defensive patterns

Strategy: validation

Validate before calling

LISTING = {"reddit", "hackernews", "digg"}
allowed = set(available_sources or []) & LISTING  # 'x' is always discarded here
if domain.strip() == "" and not allowed:
    raise SystemExit("global trending needs >=1 of reddit/hackernews/digg")

Try / catch

try:
    plan = planner.build_discovery_plan("", available_sources=srcs)
except ValueError as exc:
    if "global trending" in str(exc):
        srcs = ["reddit"]
        plan = planner.build_discovery_plan("", available_sources=srcs)
    else:
        raise

Prevention

When it happens

Trigger: build_discovery_plan called with domain='' (or whitespace) and available_sources set to values that exclude all of reddit/hackernews/digg — e.g. available_sources=['x'] (x is discarded) or available_sources=['youtube']. In the real pipeline this is pre-filtered (pipeline.py intersects with DISCOVERY_SOURCES), so hitting it usually means calling the planner directly.

Common situations: Direct planner unit-tests or custom orchestrators passing arbitrary available_sources; passing discovery's available list derived from a keyed-only config where none of the three listing sources are usable; mock runs with restricted sources.

Related errors


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/c00b44330968cd2e. Report an issue: GitHub.