{"record":{"id":"239788e66f3ee8a4","repo":"DIYgod/RSSHub","slug":"invalid-user","errorCode":null,"errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"lib/routes/itch/devlog.ts","lineNumber":41,"sourceCode":"        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: 'Developer Logs',\n    maintainers: ['nczitzk'],\n    handler,\n    description: `\\`User id\\` is the field before \\`.itch.io\\` in the URL of the corresponding page, e.g. the URL of [The Baby In Yellow Devlog](https://teamterrible.itch.io/the-baby-in-yellow/devlog) is \\`https://teamterrible.itch.io/the-baby-in-yellow/devlog\\`, where the field before \\`.itch.io\\` is \\`teamterrible\\`.\n\n\\`Item id\\` is the field between \\`itch.io\\` and \\`/devlog\\` in the URL of the corresponding page, e.g. the URL for [The Baby In Yellow Devlog](https://teamterrible.itch.io/the-baby-in-yellow/devlog) is \\`https://teamterrible.itch.io/the-baby-in-yellow/devlog\\`, where the field between \\`itch.io\\` and \\`/devlog\\` is \\`the-baby-in-yellow\\`.\n\nSo the route is [\\`/itch/devlogs/teamterrible/the-baby-in-yellow\\`](https://rsshub.app/itch/devlogs/teamterrible/the-baby-in-yellow).`,\n};\n\nasync function handler(ctx) {\n    const user = ctx.req.param('user') ?? '';\n    const id = ctx.req.param('id') ?? '';\n    const limit = Number.parseInt(ctx.req.query('limit')) || 20;\n    if (!isValidHost(user)) {\n        throw new InvalidParameterError('Invalid user');\n    }\n\n    const rootUrl = `https://${user}.itch.io/${id}/devlog`;\n\n    const response = await got({\n        method: 'get',\n        url: rootUrl,\n    });\n\n    const $ = load(response.data);\n\n    let items = $('.title')\n        .toArray()\n        .slice(0, limit)\n        .map((item): DataItem => {\n            const $item = $(item);\n\n            return {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/itch/devlog.ts#L23-L59","documentation":"Thrown by the itch.io devlog route as `InvalidParameterError('Invalid user')` when the `user` path param fails `isValidHost(user)` — i.e. the subdomain-style user id is not a valid hostname. The route builds `https://${user}.itch.io/${id}/devlog`, so `user` must be a syntactically valid host label.","triggerScenarios":"Request to `/itch/devlogs/:user/:id` where `user` contains invalid hostname characters (underscores, spaces, dots, etc.) or is empty. `isValidHost` rejects it before any HTTP call.","commonSituations":"Typo in the user slug; user pasted the full URL instead of just the subdomain part; the user field contains uppercase or special characters; the route was called with the game id in the user slot.","solutions":["Pass only the subdomain portion (the part before `.itch.io`), lowercase, hyphen-separated: `/itch/devlogs/teamterrible/the-baby-in-yellow`.","Do not include `https://` or `.itch.io` in the `user` param.","Double-check argument order: user comes first, item id second."],"exampleFix":"// before: /itch/devlogs/https://teamterrible.itch.io/the-baby-in-yellow/devlog\n// after:  /itch/devlogs/teamterrible/the-baby-in-yellow","handlingStrategy":"validation","validationCode":"if (!isValidHost(user)) throw new InvalidParameterError(`Invalid itch.io user subdomain: '${user}'`);","typeGuard":"const isValidItchUser = (u: string) => Boolean(u) && /^[a-z0-9][a-z0-9-]*$/.test(u) && isValidHost(u);","tryCatchPattern":null,"preventionTips":["Pass only the subdomain portion (lowercase, hyphen-separated) — never the full URL.","Keep arg order: user first, item id second.","Document the expected format with a worked example (the route already does)."],"tags":["itch","invalid-parameter","host-validation"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}