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
- If you are a user: pass only sources returned by `--search` validation (those are guaranteed to have normalizers).
- If you are adding a source: register a normalizer entry in the dict at the top of normalize.py.
- If the bad source came from an external plan, edit the plan to use a supported source name.
- 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 adding a source, register it in normalize.py, available_sources, and SEARCH_ALIAS together.
- Validate external plan sources against the normalizers dict before running the pipeline.
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
- Unknown search source: {source}
- --search requires at least one source.
- Unsupported emit mode: {emit}
- [last30days] Cannot read --synthesis-file: {exc}
- [CompetitorsPlan] Cannot read plan file: {exc}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/f17cb713a07c6239.
Report an issue: GitHub.