{"record":{"id":"f57dba3eac0220f7","repo":"DIYgod/RSSHub","slug":"user-not-found","errorCode":null,"errorMessage":"User Not Found","messagePattern":"User Not Found","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"error","filePath":"lib/routes/sspai/author.ts","lineNumber":17,"sourceCode":"import InvalidParameterError from '@/errors/types/invalid-parameter';\nimport type { Route } from '@/types';\nimport cache from '@/utils/cache';\nimport got from '@/utils/got';\nimport { parseDate } from '@/utils/parse-date';\n\nasync function getUserId(slug) {\n    const response = await got({\n        method: 'get',\n        url: `https://sspai.com/api/v1/user/slug/info/get?slug=${slug}`,\n        headers: {\n            Referer: `https://sspai.com/u/${slug}/posts`,\n        },\n    });\n\n    if (response.data.error !== 0) {\n        throw new InvalidParameterError('User Not Found');\n    }\n\n    return response.data.data.id;\n}\n\nexport const route: Route = {\n    path: '/author/:id',\n    categories: ['new-media'],\n    example: '/sspai/author/796518',\n    parameters: { id: '作者 slug 或 id，slug 可在作者主页URL中找到，id 不易查找，仅作兼容' },\n    features: {\n        requireConfig: false,\n        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/sspai/author.ts#L1-L35","documentation":"Thrown by getUserId (sspai/author.ts:17) as an InvalidParameterError when the sspai user-resolution API (/api/v1/user/slug/info/get?slug=...) returns a non-zero error code. The handler only calls getUserId when the :id param is NOT pure digits (line 47: /^\\d+/.test), so a numeric id bypasses this lookup entirely; slugs go through it. Because it is an InvalidParameterError, RSSHub surfaces it as an HTTP 400 with a localized 'invalid parameter' body rather than a 500.","triggerScenarios":"Requesting /sspai/author/<slug> where <slug> is a non-numeric string sspai does not recognize: a typo, a renamed/deleted account, or a slug containing characters sspai rejects. Also fires if a numeric id is passed with a stray letter/space so the /^\\d+$/ regex fails and the value is treated as a slug.","commonSituations":"Copying a slug from an old/cached URL after the author renamed their sspai handle; the author deleted their account; pasting the numeric id with leading/trailing whitespace or a trailing letter; confusing the slug with the display name.","solutions":["Use the numeric author id form (e.g. /sspai/author/796518) — it skips the slug lookup entirely and cannot hit this error.","Open https://sspai.com/u/<slug>/posts in a browser; if it 404s, the slug is wrong or the user is gone.","Re-copy the slug verbatim from the current author-page URL on sspai.com (the path segment after /u/)."],"exampleFix":"// request - before\nGET /sspai/author/john-doe-renamed\n// request - after (use numeric id, or the correct current slug)\nGET /sspai/author/796518","handlingStrategy":"validation","validationCode":"// Pre-check before depending on the slug resolving.\n// Numeric ids bypass getUserId entirely; prefer them.\nfunction prefersNumericId(id: string): boolean {\n  return /^\\d+$/.test(id);\n}\n\n// If you must accept a slug, sanity-check it is non-empty and roughly\n// slug-shaped before the route hits the sspai API.\nfunction isPlausibleSspaiSlug(id: string): boolean {\n  return typeof id === 'string' && id.trim().length > 0 && /^[a-zA-Z0-9_-]+$/.test(id);\n}","typeGuard":"// Prefer the numeric-id form to skip the slug lookup entirely.\nfunction isNumericAuthorId(id: string): id is string {\n  return /^\\d+$/.test(id);\n}","tryCatchPattern":"try {\n  await fetchFeed('/sspai/author/' + id);\n} catch (e) {\n  if (e instanceof Error && e.message === 'User Not Found') {\n    // surface a friendly 'unknown slug' message; suggest numeric id\n  }\n  throw e;\n}","preventionTips":["Prefer the numeric author id (/sspai/author/796518) — it cannot throw this error.","Source the slug only from the current sspai.com author URL, not from cached links.","Strip whitespace from user-supplied ids before using them."],"tags":["invalid-parameter","user-input","api-validation","sspai"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}