DIYgod/RSSHub · error · Error

Invalid tab: ${finalSearchParams.tab}

Error message

Invalid tab: ${finalSearchParams.tab}

What it means

Thrown by the Voronoi `getPostItems` helper when the `tab` parameter, after uppercasing, is not one of the values in the `TabMap` object (`POPULAR`, `DISCUSSED`, `VIEWED`). The check uses `Object.values(TabMap).includes()`. This is a generic `Error`. Note the `TabMap` keys are lowercase kebab (`most-popular`) but the values are uppercase (`POPULAR`) — this validation checks the value side.

Source

Thrown at lib/routes/voronoiapp/common.ts:47

        if (TimeRangeParam.options.every((option) => option.value !== finalSearchParams.time_range)) {
            throw new Error(`Invalid time range: ${finalSearchParams.time_range}`);
        }
        // The Voronoi API doesn't support "ALL"
        if (finalSearchParams.time_range === 'ALL') {
            finalSearchParams.time_range = undefined;
        }
    }
    if (finalSearchParams.category !== undefined && finalSearchParams.category !== null) {
        const category = finalSearchParams.category;
        finalSearchParams.category = CategoryParam.options.find((option) => option.value.toLowerCase() === category.toLowerCase())?.value;
        if (finalSearchParams.category === undefined) {
            throw new Error(`Invalid category: ${finalSearchParams.category}`);
        }
    }
    if (finalSearchParams.tab !== undefined && finalSearchParams.tab !== null) {
        finalSearchParams.tab = finalSearchParams.tab.toUpperCase();
        if (!Object.values(TabMap).includes(finalSearchParams.tab)) {
            throw new Error(`Invalid tab: ${finalSearchParams.tab}`);
        }
    }
    for (const key in finalSearchParams) {
        if (finalSearchParams[key] !== undefined && finalSearchParams[key] !== null) {
            url.searchParams.set(key, finalSearchParams[key]);
        }
    }
    const data = await ofetch<Post[]>(url.href);
    const items: DataItem[] = data.map((post) => ({
        title: post.headline,
        link: `https://www.voronoiapp.com/${post.category.split(' ').join('-').toLowerCase()}/${post.link}`,
        pubDate: parseDate(post.published_at),
        description: `<img src="https://cdn.voronoiapp.com/public/${post.webp_image}" />
        ${post.description}`,
        image: `https://cdn.voronoiapp.com/public/${post.webp_image}`,
        author: post.author.first_name + ' ' + post.author.last_name,
        updated: parseDate(post.updated_at),
        category: [post.category],

View on GitHub (pinned to bed535e087)

Solutions

  1. Use one of `POPULAR`, `DISCUSSED`, or `VIEWED` as the tab value (uppercase).
  2. In the popular route, use the lowercase path keys: `most-popular`, `most-discussed`, `most-viewed`.
  3. If calling `getPostItems` directly, map through `TabMap` first.

Example fix

// before
tab: 'TRENDING'
// after
tab: TabMap['most-popular']  // 'POPULAR'
Defensive patterns

Strategy: validation

Validate before calling

const VALID_TABS = Object.values(TabMap); // ['POPULAR', 'DISCUSSED', 'VIEWED']
if (tab && !VALID_TABS.includes(tab.toUpperCase())) {
    throw new InvalidParameterError(`Invalid tab: ${tab}. Valid: ${VALID_TABS.join(', ')}`);
}

Type guard

function isValidTabValue(tab: string): tab is 'POPULAR' | 'DISCUSSED' | 'VIEWED' {
    return Object.values(TabMap).includes(tab.toUpperCase() as any);
}

Prevention

When it happens

Trigger: Calling `getPostItems({ tab: 'TRENDING' })` or any uppercase string not in `TabMap`'s values. In the popular route, the `tab` path parameter is mapped from its lowercase key (e.g. `most-popular`) to its uppercase value (e.g. `POPULAR`) before calling `getPostItems`, so a valid popular-route tab should always pass this check — unless `getPostItems` is called directly with a bad value.

Common situations: A code change in the popular route passes an unmapped tab value, or a developer calls `getPostItems` directly with a raw user input. The popular route (line 34) has its own separate `Object.hasOwn(TabMap, ...)` check that guards against this before the mapping.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/3e94fd33e4a435cd. Report an issue: GitHub.