DIYgod/RSSHub · warning · InvalidParameterError
Provide a valid Misskey username
Error message
Provide a valid Misskey username
What it means
Thrown as InvalidParameterError by the Misskey user-timeline route when the :username parameter does not match the regex /@?(\w+)@(\w+\.\w+)/ — i.e. it is not a WebFinger 'acct' style identifier (user@host.tld, with optional leading @). The regex captures both the pure username and the host; failure to capture either is a client error.
Source
Thrown at lib/routes/misskey/user-timeline.ts:49
},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
name: 'User timeline',
maintainers: ['siygle', 'SnowAgar25', 'HanaokaYuzu'],
handler,
};
async function handler(ctx): Promise<Data> {
const username = ctx.req.param('username');
const [, pureUsername, site] = username.match(/@?(\w+)@(\w+\.\w+)/) || [];
if (!pureUsername || !site) {
throw new InvalidParameterError('Provide a valid Misskey username');
}
if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) {
throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
}
const routeParams = querystring.parse(ctx.req.param('routeParams'));
const withRenotes = fallback(undefined, queryToBoolean(routeParams.withRenotes), false);
const mediaOnly = fallback(undefined, queryToBoolean(routeParams.mediaOnly), false);
const simplifyAuthor = fallback(undefined, queryToBoolean(routeParams.simplifyAuthor), false);
// Check for conflicting parameters
if (withRenotes && mediaOnly) {
throw new InvalidParameterError('withRenotes and mediaOnly cannot both be true.');
}
const { accountData, avatarUrl } = await utils.getUserTimelineByUsername(pureUsername, site, {
withRenotes,
mediaOnly,View on GitHub (pinned to bed535e087)
Solutions
- Format the username as an acct: '@user@instance.tld' or 'user@instance.tld' (the leading @ is optional), e.g. /misskey/user/@alice@misskey.io.
- Ensure the host part has at least one dot (a real domain).
- Strip any surrounding URL scheme or path before passing the value.
Defensive patterns
Strategy: validation
Validate before calling
const username = ctx.req.param('username');
const m = username.match(/^@?(\w+)@(\w+\.\w+)$/);
if (!m) {
throw new InvalidParameterError(`Provide a username in acct form user@host.tld (leading @ optional); got: ${username}`);
}
const [, pureUsername, site] = m; Type guard
function isAcct(username: string): boolean {
return typeof username === 'string' && /^@?\w+@\w+\.\w+$/.test(username);
} Prevention
- Always build the parameter as user@host.tld, not a bare handle or URL.
- Document the acct format prominently in the route parameters.
- Reject values containing '://' early in any client feed-URL builder.
When it happens
Trigger: Caller requests /misskey/user-timeline/:username with a value like 'alice' (no host), 'alice@' (no domain), '@alice@host' where host has no dot, or a value containing characters outside \w. pureUsername or site is undefined, so it throws.
Common situations: User supplies just the handle without the instance domain; user supplies a URL instead of an acct; the instance host is a single-label name without a TLD (rare).
Related errors
- withRenotes and mediaOnly cannot both be true.
- Invalid Engine Value: ${engine}, please check your config.
- Invalid domain
- Invalid number
- Invalid domain
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/f8fed3577079f2d9.
Report an issue: GitHub.