DIYgod/RSSHub · error · Error
Invalid URL
Error message
Invalid URL
What it means
The url parameter is validated against ^https?:\/\/[^\s#$./?].\S*$ (case-insensitive) before any fetch. It requires an http/https scheme, no whitespace/fragment/query metacharacters in the first character, and at least one more character after the scheme prefix. A non-match throws a plain Invalid URL.
Source
Thrown at lib/routes/wordpress/index.ts:21
import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import type { Data, Route } from '@/types';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
import parser from '@/utils/rss-parser';
import { apiSlug, bakeFilterSearchParams, bakeFiltersWithPair, bakeUrl, fetchData, getFilterParamsForUrl, parseFilterStr } from './util';
async function handler(ctx) {
const { url = 'https://wordpress.org/news', filter } = ctx.req.param();
const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50;
if (!config.feature.allow_user_supply_unsafe_domain) {
throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
}
if (!/^https?:\/\/[^\s#$./?].\S*$/i.test(url)) {
throw new Error('Invalid URL');
}
const cdn = config.wordpress.cdnUrl;
const rootUrl = url;
const filters = parseFilterStr(filter);
const filtersWithPair = await bakeFiltersWithPair(filters, rootUrl);
const searchParams = bakeFilterSearchParams(filters, 'name', false);
const apiSearchParams = bakeFilterSearchParams(filtersWithPair, 'id', true);
apiSearchParams.append('_embed', 'true');
apiSearchParams.append('per_page', String(limit));
const apiUrl = bakeUrl(`${apiSlug}/posts`, rootUrl, apiSearchParams);
const currentUrl = bakeUrl(getFilterParamsForUrl(filtersWithPair) ?? '', rootUrl, searchParams);
try {View on GitHub (pinned to bed535e087)
Solutions
- Ensure the url starts with http:// or https:// and has no spaces.
- URL-encode the whole url when placing it in the route path (encodeURIComponent).
- Use the documented default by omitting url, or pass a fully-qualified wordpress root.
Example fix
// before /wordpress/wordpress.org/news // after /wordpress/https%3A%2F%2Fwordpress.org%2Fnews
Defensive patterns
Strategy: validation
Validate before calling
function isValidWordpressUrl(u: string): boolean {
return /^https?:\/\/[^\s#$./?].\S*$/i.test(u);
}
if (!isValidWordpressUrl(url)) {
throw new InvalidParameterError('url must be a fully-qualified http(s) URL');
} Type guard
function isWordpressInvalidUrlError(e: unknown): boolean {
return e instanceof Error && e.message === 'Invalid URL';
} Try / catch
try {
return await wordpressHandler(ctx);
} catch (e) {
if (isWordpressInvalidUrlError(e)) {
return ctx.json({ error: 'Invalid url parameter. Encode it with encodeURIComponent and include the scheme.' }, 400);
}
throw e;
} Prevention
- Always encodeURIComponent the url before placing it in the route path.
- Include the http:// or https:// scheme — the regex requires it.
- Throw InvalidParameterError (not generic Error) so RSSHub returns 4xx for bad input.
When it happens
Trigger: Passing a url without a scheme (example.com), with spaces, with a leading # or ? , a single-char host, or a malformed/encoded value that breaks the pattern at wordpress/index.ts:20.
Common situations: User forgot to URL-encode the value, passed a bare domain, or the leading char is one of the excluded set (#$./?).
Related errors
- Invalid category: ${categoryParam}. Valid categories are: ${
- Invalid type parameter
- Invalid type parameter
- Invalid category: ${category}
- Unsupported region code: ${region}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/164610438a1a1b23.
Report an issue: GitHub.