{"record":{"id":"97dc8e047754efbe","repo":"DIYgod/RSSHub","slug":"invalid-account","errorCode":null,"errorMessage":"Invalid account","messagePattern":"Invalid account","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"warning","filePath":"lib/routes/fediverse/timeline.ts","lineNumber":38,"sourceCode":"        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: 'Timeline',\n    maintainers: ['DIYgod', 'pseudoyu'],\n    handler,\n};\n\nconst allowedDomain = new Set(['mastodon.social', 'pawoo.net', config.mastodon.apiHost].filter(Boolean));\nconst activityPubTypes = new Set(['application/activity+json', 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"']);\n\nasync function handler(ctx) {\n    const account = ctx.req.param('account');\n    const domain = account.split('@', 2)[1];\n    const username = account.split('@', 1)[0];\n\n    if (!domain || !username) {\n        throw new InvalidParameterError('Invalid account');\n    }\n    if (!config.feature.allow_user_supply_unsafe_domain && !allowedDomain.has(domain.toLowerCase())) {\n        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);\n    }\n\n    const requestOptions = {\n        headers: {\n            Accept: 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"',\n        },\n    };\n\n    const acc = await ofetch(`https://${domain}/.well-known/webfinger?resource=acct:${account}`, {\n        headers: {\n            Accept: 'application/jrd+json',\n        },\n    });\n    const jsonLink = acc.links.find((link) => link.rel === 'self' && activityPubTypes.has(link.type))?.href;\n    const link = acc.links.find((link) => link.rel === 'http://webfinger.net/rel/profile-page')?.href;","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/fediverse/timeline.ts#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use the format `username@domain`, e.g., `/fediverse/timeline/Mastodon@mastodon.social`.","Avoid the `@user@domain` ActivityPub URI format — this route expects `user@domain` (leading @ is acceptable but the first segment becomes username).","Do not include `https://` or a protocol prefix in the parameter."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function parseAccount(account: string): { username: string; domain: string } {\n    const parts = account.split('@');\n    // Handle @user@domain (ActivityPub format) or user@domain\n    const username = parts.length === 3 ? parts[1] : parts[0];\n    const domain = parts.length === 3 ? parts[2] : parts[1];\n    if (!username || !domain) {\n        throw new InvalidParameterError('Account must be in format username@domain');\n    }\n    return { username, domain };\n}","typeGuard":"function isValidAccountFormat(account: string): boolean {\n    const parts = account.split('@');\n    // Accept user@domain or @user@domain\n    return parts.length >= 2 && parts[parts.length - 1].length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always use the format username@domain (e.g., Mastodon@mastodon.social).","Avoid leading @ unless using ActivityPub format (@user@domain).","Do not pass full URLs as the account parameter.","Test the account format with a webfinger lookup before using it in the route."],"tags":["parameter-validation","format-validation","fediverse","mastodon","invalid-parameter-error"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}