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
- 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.
- Omit the city segment entirely to default to 'www'.
- 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
- Never include the scheme or '.19lou.com' in the city parameter.
- If unsure, omit the segment to use the 'www' default.
- Treat isValidHost as a security boundary, not a convenience — don't bypass it.
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
- Invalid pub
- Bad timeRange range. See <a href="https://docs.rsshub.app/ro
- Bad parameter. See <a href="https://docs.rsshub.app/routes/g
- Invalid channel name
- This category does not exist. Please refer to the documentat
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/d8c8a9ca5312a385.
Report an issue: GitHub.