DIYgod/RSSHub · error · InvalidParameterError

Invalid city

Error message

Invalid city

What it means

19lou is a regional forum network with per-city subdomains; the route builds `https://${city}.19lou.com`. isValidHost rejects values that are not a safe single DNS label, which prevents host injection / SSRF via dots, slashes, or special characters. InvalidParameterError is thrown when the city segment fails the check.

Source

Thrown at lib/routes/19lou/index.ts:57

| www  | taizhou | jiaxing | ningbo | huzhou |

| 绍兴     | 湖州   | 温州    | 金华   | 舟山     |
| -------- | ------ | ------- | ------ | -------- |
| shaoxing | huzhou | wenzhou | jinhua | zhoushan |

| 衢州   | 丽水   | 义乌 | 萧山     | 余杭   |
| ------ | ------ | ---- | -------- | ------ |
| quzhou | lishui | yiwu | xiaoshan | yuhang |

| 临安  | 富阳   | 桐庐   | 建德   | 淳安   |
| ----- | ------ | ------ | ------ | ------ |
| linan | fuyang | tonglu | jiande | chunan |`,
};

async function handler(ctx) {
    const city = ctx.req.param('city') ?? 'www';
    if (!isValidHost(city)) {
        throw new InvalidParameterError('Invalid city');
    }

    const rootUrl = `https://${city}.19lou.com`;

    const response = await got({
        method: 'get',
        url: rootUrl,
        responseType: 'buffer',
    });

    const $ = load(iconv.decode(response.data, 'gbk'));

    $('.title-more').remove();

    let items = $('.center-center-jiazi')
        .find('a[title]')
        .toArray()
        .map((item): DataItem & { link: string } => {

View on GitHub (pinned to bed535e087)

Solutions

  1. Use one of the documented city slugs: www, hangzhou, ningbo, wenzhou, jiaxing, huzhou, shaoxing, jinhua, quzhou, lishui, yiwu, xiaoshan, yuhang, linan, fuyang, tonglu, jiande, chunan.
  2. Omit the city segment entirely to default to 'www'.
  3. Do not include the scheme or '.19lou.com' suffix in the parameter.

Example fix

// before
/19lou/hangzhou.19lou.com
// after
/19lou/hangzhou
Defensive patterns

Strategy: validation

Validate before calling

import { isValidHost } from '@/utils/valid-host';
const CITIES_19LOU = new Set(['www','hangzhou','ningbo','wenzhou','jiaxing','huzhou','shaoxing','jinhua','quzhou','lishui','yiwu','xiaoshan','yuhang','linan','fuyang','tonglu','jiande','chunan']);
function valid19louCity(city) {
  return CITIES_19LOU.has(city) && isValidHost(city);
}

Type guard

function is19louCity(c): boolean {
  return typeof c === 'string' && /^[a-z]+$/.test(c) && CITIES_19LOU.has(c);
}

Prevention

When it happens

Trigger: Calling /19lou/:city with a slug that is not in the documented city list, or that contains '.', '/', '@', or other non-hostname characters.

Common situations: Guessing a city slug; typo; copying a full URL into the city slot; upstream added a city not yet reflected in docs.

Related errors


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