DIYgod/RSSHub · warning · Error

Unknown category: ${category}. Supported: ${Object.keys(APP_

Error message

Unknown category: ${category}. Supported: ${Object.keys(APP_CATEGORY_MAP).join(', ')}

What it means

The theinitium app route maps the :category path param through APP_CATEGORY_MAP to a {channelType, language} pair. If the provided category is not a key in that map, it throws an Error listing the supported keys, so the caller knows which values are accepted.

Source

Thrown at lib/routes/theinitium/app.ts:104

| 速递  | whats\\_new\\_sc    | whats\\_new\\_tc    |
| 专题  | report\\_sc        | report\\_tc        |
| 评论  | opinion\\_sc       | opinion\\_tc       |
| 国际  | international\\_sc | international\\_tc |
| 大陆  | mainland\\_sc      | mainland\\_tc      |
| 香港  | hongkong\\_sc      | hongkong\\_tc      |
| 台湾  | taiwan\\_sc        | taiwan\\_tc        |

::: tip
原 App 路由已迁移至 Ghost CMS API。播客(article\\_audio)分类已停用,请改用 \`/theinitium/channel\` 路由。
:::`,
};

async function handler(ctx) {
    const category = ctx.req.param('category') ?? 'latest_sc';

    const mapping = APP_CATEGORY_MAP[category];
    if (!mapping) {
        throw new Error(`Unknown category: ${category}. Supported: ${Object.keys(APP_CATEGORY_MAP).join(', ')}`);
    }

    const { channelType, language } = mapping;

    // Reason: Reuse the same Ghost tag filter logic as processFeed's channel case
    const baseTag = CHANNEL_TAG_MAP[channelType] ?? channelType;
    let filter = '';
    if (baseTag === '') {
        // "latest" = no tag filter, just filter by language via internal tag
        filter = `tag:hash-${language}`;
    } else {
        const tagSlug = applyLanguageToTagSlug(baseTag, language);
        filter = `tag:${tagSlug}`;
    }

    const params: Record<string, string> = {
        include: 'tags,authors',
        limit: '20',

View on GitHub (pinned to bed535e087)

Solutions

  1. Use one of the categories listed in the error message (the keys of APP_CATEGORY_MAP).
  2. Omit the category to fall back to the default 'latest_sc'.
  3. If a real channel is missing, add it to APP_CATEGORY_MAP with the correct channelType and language.

Example fix

// before
const mapping = APP_CATEGORY_MAP[category];
if (!mapping) {
    throw new Error(`Unknown category: ${category}. Supported: ${Object.keys(APP_CATEGORY_MAP).join(', ')}`);
}

// after: throw an InvalidParameterError (RSS idiom) and hint the default
const mapping = APP_CATEGORY_MAP[category];
if (!mapping) {
    throw new InvalidParameterError(`Unknown category "${category}". Supported: ${Object.keys(APP_CATEGORY_MAP).join(', ')} (default: latest_sc)`);
}
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set(Object.keys(APP_CATEGORY_MAP));
function isSupportedCategory(c: string): boolean {
    return SUPPORTED.has(c);
}
// expose valid categories via the route docs; default to 'latest_sc'

Type guard

function isAppCategory(c: string): c is keyof typeof APP_CATEGORY_MAP {
    return c in APP_CATEGORY_MAP;
}

Try / catch

try {
    return await handler(ctx);
} catch (e) {
    if (e instanceof Error && /Unknown category/.test(e.message)) {
        return badRequest(`Use one of: ${Object.keys(APP_CATEGORY_MAP).join(', ')}`);
    }
    throw e;
}

Prevention

When it happens

Trigger: Requesting /theinitium/app/<category> with a category that is not one of the predefined keys (e.g. an old or typo'd channel name). The default category is 'latest_sc'.

Common situations: User copies a channel name from the website that is not in APP_CATEGORY_MAP; the map was refactored and a previously-valid category was removed/renamed; typo in the URL.

Related errors


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