DIYgod/RSSHub · warning · InvalidParameterError

Invalid account

Error message

Invalid account

What it means

Thrown as an `InvalidParameterError` when the `account` path parameter cannot be split into a username and domain. The route expects the format `username@domain` (e.g., `Mastodon@mastodon.social`). It splits on `@`: `account.split('@', 2)[1]` yields the domain, `account.split('@', 1)[0]` yields the username. If either is missing (no `@`, or `@` at start/end), the check fails.

Source

Thrown at lib/routes/fediverse/timeline.ts:38

        supportBT: false,
        supportPodcast: false,
        supportScihub: false,
    },
    name: 'Timeline',
    maintainers: ['DIYgod', 'pseudoyu'],
    handler,
};

const allowedDomain = new Set(['mastodon.social', 'pawoo.net', config.mastodon.apiHost].filter(Boolean));
const activityPubTypes = new Set(['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"']);

async function handler(ctx) {
    const account = ctx.req.param('account');
    const domain = account.split('@', 2)[1];
    const username = account.split('@', 1)[0];

    if (!domain || !username) {
        throw new InvalidParameterError('Invalid account');
    }
    if (!config.feature.allow_user_supply_unsafe_domain && !allowedDomain.has(domain.toLowerCase())) {
        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
    }

    const requestOptions = {
        headers: {
            Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
        },
    };

    const acc = await ofetch(`https://${domain}/.well-known/webfinger?resource=acct:${account}`, {
        headers: {
            Accept: 'application/jrd+json',
        },
    });
    const jsonLink = acc.links.find((link) => link.rel === 'self' && activityPubTypes.has(link.type))?.href;
    const link = acc.links.find((link) => link.rel === 'http://webfinger.net/rel/profile-page')?.href;

View on GitHub (pinned to bed535e087)

Solutions

  1. Use the format `username@domain`, e.g., `/fediverse/timeline/Mastodon@mastodon.social`.
  2. Avoid the `@user@domain` ActivityPub URI format — this route expects `user@domain` (leading @ is acceptable but the first segment becomes username).
  3. Do not include `https://` or a protocol prefix in the parameter.
Defensive patterns

Strategy: validation

Validate before calling

function parseAccount(account: string): { username: string; domain: string } {
    const parts = account.split('@');
    // Handle @user@domain (ActivityPub format) or user@domain
    const username = parts.length === 3 ? parts[1] : parts[0];
    const domain = parts.length === 3 ? parts[2] : parts[1];
    if (!username || !domain) {
        throw new InvalidParameterError('Account must be in format username@domain');
    }
    return { username, domain };
}

Type guard

function isValidAccountFormat(account: string): boolean {
    const parts = account.split('@');
    // Accept user@domain or @user@domain
    return parts.length >= 2 && parts[parts.length - 1].length > 0;
}

Prevention

When it happens

Trigger: A user passes just a username without a domain (e.g., `/fediverse/timeline/Mastodon`), just a domain, or an empty string. The split produces `undefined` for domain or username, triggering the guard before any webfinger request.

Common situations: User misunderstands the expected format and passes a URL (`https://mastodon.social/@Mastodon`) or a bare username. A URL encoding issue strips the `@` character. The user passes `@user@domain` (ActivityPub format) which causes split('@', 2)[1] to return `user` as the domain instead of the real domain.

Related errors


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