{"record":{"id":"437aab21183a68b2","repo":"DIYgod/RSSHub","slug":"invalid-language-437aab","errorCode":null,"errorMessage":"Invalid language","messagePattern":"Invalid language","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"warning","filePath":"lib/routes/pornhub/model.ts","lineNumber":41,"sourceCode":"        requireConfig: false,\n        requirePuppeteer: false,\n        antiCrawler: true,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n        nsfw: true,\n    },\n    radar: getRadarDomin('/model/:username'),\n    name: 'Model',\n    maintainers: ['I2IMk', 'queensferryme'],\n    handler,\n};\n\nasync function handler(ctx): Promise<Data> {\n    const { language = 'www', username, sort = '', img } = ctx.req.param();\n    const link = `https://${language}.pornhub.com/model/${username}/videos${sort ? `?o=${sort}` : ''}`;\n    if (!isValidHost(language)) {\n        throw new InvalidParameterError('Invalid language');\n    }\n\n    const { data: response } = await got(link, { headers });\n    const $ = load(response);\n    const showImages = img === 'img=1';\n    const items = $('#mostRecentVideosSection .videoBox')\n        .toArray()\n        .map((e) => parseItems($(e), showImages));\n\n    return {\n        title: $('h1').first().text(),\n        description: $('section.aboutMeSection').text().trim(),\n        link,\n        image: $('#getAvatar').attr('src'),\n        language: $('html').attr('lang') as any,\n        item: items,\n    };\n}","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/pornhub/model.ts#L23-L59","documentation":"InvalidParameterError thrown by the Pornhub model handler when the language path segment fails isValidHost. Identical guard to the category_url route: the language is interpolated into https://{language}.pornhub.com/model/... and must be a valid DNS-label subdomain, otherwise the request is rejected before fetching.","triggerScenarios":"Passing a language segment containing dots, slashes, underscores, spaces, special characters, or an empty string; using a full locale identifier instead of a bare subdomain code.","commonSituations":"User passes 'en-US' style locales; adds a trailing dot or slash; leaves an encoded character; uses a code Pornhub lacks a subdomain for.","solutions":["Use a bare lowercase Pornhub language subdomain code such as www, cn, jp, fr, de.","Keep the segment free of dots, slashes, spaces, and special characters.","Omit language to default to 'www'.","Verify the subdomain exists (e.g. https://cn.pornhub.com) before using a code."],"exampleFix":"// before: /pornhub/model/username/www.\n// after:  /pornhub/model/username/www","handlingStrategy":"validation","validationCode":"import { isValidHost } from '@/utils/valid-host';\nfunction isValidLanguageSegment(lang: string): boolean {\n  return typeof lang === 'string' && lang.length > 0 && isValidHost(lang);\n}\nif (!isValidLanguageSegment(language)) {\n  // reject before building the pornhub model URL\n}","typeGuard":"const isValidLanguageSegment = (lang: unknown): lang is string =>\n  typeof lang === 'string' && /^[\\dA-Z](?:[\\dA-Z-]{0,61}[\\dA-Z])?$/i.test(lang);","tryCatchPattern":"try {\n  // model handler\n} catch (e) {\n  if (e instanceof InvalidParameterError && /Invalid language/.test(e.message)) {\n    // surface allowed language subdomain codes\n  }\n}","preventionTips":["Restrict language to bare subdomain codes (www, cn, jp, ...).","Reject segments containing dots, slashes, spaces, or special characters.","Default to 'www' when the segment is omitted."],"tags":["pornhub","invalid-parameter","validation","language","host"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}