{"record":{"id":"920a61fa206ed3fb","repo":"DIYgod/RSSHub","slug":"invalid-name","errorCode":null,"errorMessage":"Invalid name","messagePattern":"Invalid name","errorType":"exception","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"lib/routes/lofter/user.ts","lineNumber":31,"sourceCode":"    parameters: { name: 'Lofter user name, can be found in the URL' },\n    features: {\n        requireConfig: false,\n        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: 'User',\n    maintainers: ['hondajojo', 'nczitzk', 'LucunJi'],\n    handler,\n};\n\nasync function handler(ctx) {\n    const name = ctx.req.param('name') ?? 'i';\n    const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : '50';\n    if (!isValidHost(name)) {\n        throw new InvalidParameterError('Invalid name');\n    }\n\n    const rootUrl = `${name}.lofter.com`;\n\n    const response = await got({\n        method: 'post',\n        url: 'http://api.lofter.com/v2.0/blogHomePage.api?product=lofter-iphone-10.0.0',\n        body: new URLSearchParams({\n            blogdomain: rootUrl,\n            checkpwd: '1',\n            following: '0',\n            limit: String(limit),\n            method: 'getPostLists',\n            needgetpoststat: '1',\n            offset: '0',\n            postdigestnew: '1',\n            supportposttypes: '1,2,3,4,5,6',\n        }),","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/lofter/user.ts#L13-L49","documentation":"Thrown by the Lofter user handler (lib/routes/lofter/user.ts:31) as an `InvalidParameterError` when the `:name` path parameter fails `isValidHost()`. The name is interpolated into a subdomain (`${name}.lofter.com`), so it must be a valid DNS label.","triggerScenarios":"Requesting `/lofter/user/<name>/...` where `<name>` contains dots, slashes, spaces, or other invalid hostname characters; passing a full URL or blog path instead of the bare subdomain label.","commonSituations":"Passing `name.lofter.com` instead of `name`; trailing slash; uppercase; underscores.","solutions":["Pass only the bare subdomain label, e.g. `/lofter/user/i` (the documented default).","Strip protocol/host/path from the value before calling the route.","Verify `<name>.lofter.com` resolves in a browser."],"exampleFix":"// before: GET /lofter/user/myblog.lofter.com\n// after:  GET /lofter/user/myblog","handlingStrategy":"validation","validationCode":"import { isValidHost } from '@/utils/valid-host';\nfunction resolveLofterUserName(name: string | undefined): string {\n    const n = (name ?? 'i').trim();\n    if (!isValidHost(n)) throw new TypeError(`Invalid Lofter user name: '${name}'`);\n    return n;\n}","typeGuard":"function isLofterUserName(value: string): boolean {\n    return /^[a-z0-9-]+$/i.test(value) && !value.includes('.');\n}","tryCatchPattern":"import { InvalidParameterError } from '@/errors/types/invalid-parameter';\ntry {\n    await fetchLofterUser(name);\n} catch (e) {\n    if (e instanceof InvalidParameterError && /Invalid name/.test(e.message)) {\n        return { error: `Pass a bare subdomain label, not '${name}'` };\n    }\n    throw e;\n}","preventionTips":["Pass the subdomain label only (no dots, no protocol).","Trim/lowercase input before validation.","Document that `name` becomes `<name>.lofter.com`."],"tags":["invalid-input","route-parameter","dns-validation","lofter"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}