nexu-io/open-design · error · ValueError

Unsupported source: {source}

Error message

Unsupported source: {source}

What it means

normalize.py builds a `normalizers` dict mapping known source names (youtube, reddit, x, truthsocial, threads, xquik, pinterest, polymarket, grounding, xiaohongshu, github, perplexity, and others in the table) to per-source normalizer callables. If `source` is absent from the dict, `normalizer is None` and the function raises ValueError(f"Unsupported source: {source}"). This is a programmer/contract error, not a user-config one — the source list should already have been validated upstream (e.g. by parse_search_flag and pipeline.available_sources).

Source

Thrown at design-templates/last30days/scripts/lib/normalize.py:59

        "x": _normalize_x,
        "youtube": _normalize_youtube,
        "tiktok": lambda s, i, idx, fd, td: _normalize_shortform_video(s, i, idx, fd, td, "TK", "TikTok post"),
        "instagram": lambda s, i, idx, fd, td: _normalize_shortform_video(s, i, idx, fd, td, "IG", "Instagram reel"),
        "hackernews": _normalize_hackernews,
        "bluesky": lambda s, i, idx, fd, td: _normalize_microblog(s, i, idx, fd, td, "BS", "Bluesky post"),
        "truthsocial": lambda s, i, idx, fd, td: _normalize_microblog(s, i, idx, fd, td, "TS", "Truth Social post"),
        "threads": lambda s, i, idx, fd, td: _normalize_microblog(s, i, idx, fd, td, "TH", "Threads post"),
        "xquik": _normalize_x,
        "pinterest": _normalize_pinterest,
        "polymarket": _normalize_polymarket,
        "grounding": _normalize_grounding,
        "xiaohongshu": _normalize_grounding,
        "github": _normalize_github,
        "perplexity": _normalize_grounding,
    }
    normalizer = normalizers.get(source)
    if normalizer is None:
        raise ValueError(f"Unsupported source: {source}")
    normalized = [normalizer(source, item, index, from_date, to_date) for index, item in enumerate(items)]
    require_date = source == "grounding"
    filtered = filter_by_date_range(normalized, from_date, to_date, require_date=require_date)
    if filtered:
        return filtered
    if freshness_mode == "evergreen_ok" and source == "youtube":
        if require_date:
            return [item for item in normalized if item.published_at]
        return normalized
    return filtered


def _remap_comments(
    raw: list[Any],
    score_keys: tuple[str, ...],
    excerpt_keys: tuple[str, ...],
) -> list[dict[str, Any]]:
    """Normalize comments from any source into the shared Reddit-compatible shape.

View on GitHub (pinned to 5be4028344)

Solutions

  1. If you are a user: pass only sources returned by `--search` validation (those are guaranteed to have normalizers).
  2. If you are adding a source: register a normalizer entry in the dict at the top of normalize.py.
  3. If the bad source came from an external plan, edit the plan to use a supported source name.
  4. Grep `normalizers = {` in normalize.py to list all currently supported source keys.

Example fix

# before (external plan emits a source the build lacks)
plan = {"acme": [{"source": "googlenews", ...}]}
# after
plan = {"acme": [{"source": "grounding", ...}]}
Defensive patterns

Strategy: type-guard

Validate before calling

from lib.normalize import _NORMALIZERS  # or re-derive the dict
SUPPORTED = set(_NORMALIZERS.keys())
if source not in SUPPORTED:
    raise ValueError(f'Unsupported source: {source!r}; known: {sorted(SUPPORTED)}')

Type guard

def is_supported_source(name: object, known: set[str]) -> bool:
    return isinstance(name, str) and name in known

Prevention

When it happens

Trigger: Calling normalize.normalize_items(items, source="googlenews", ...) where 'googlenews' is not a key in the normalizers table; a planner/external plan emits a subquery source name that has no normalizer; a typo introduced when adding a new source (registered in available_sources but not in normalizers).

Common situations: Adding a new source and forgetting the normalize.py entry; an external --plan that names a source the local build does not recognize; mismatch between two builds where one added a source.

Related errors


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