{"record":{"id":"afade5d1db2f91ed","repo":"DIYgod/RSSHub","slug":"medium-user-cookie-afade5","errorCode":null,"errorMessage":"缺少 Medium 用户 ${user} 登录后的 Cookie 值","messagePattern":"缺少 Medium 用户 (.+?) 登录后的 Cookie 值","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":null,"severity":"error","filePath":"lib/routes/medium/tag.ts","lineNumber":42,"sourceCode":"        supportScihub: false,\n    },\n    name: 'Personalized Recommendations - Tag',\n    maintainers: ['ImSingee'],\n    handler,\n    description: `There are many tags, which can be obtained by clicking on a tag from the homepage and looking at the URL. For example, if the URL is \\`https://medium.com/?tag=web3\\`, then the tag is \\`web3\\`.\n\n::: warning\nPersonalized recommendations require the cookie value after logging in, so only self-hosting is supported. See the configuration module on the deployment page for details.\n:::`,\n};\n\nasync function handler(ctx) {\n    const user = ctx.req.param('user');\n    const tag = ctx.req.param('tag');\n\n    const cookie = config.medium.cookies[user];\n    if (cookie === undefined) {\n        throw new ConfigNotFoundError(`缺少 Medium 用户 ${user} 登录后的 Cookie 值`);\n    }\n\n    const posts = await getWebInlineTopicFeedQuery(user, tag, cookie);\n    ctx.set('json', posts);\n\n    if (!posts) {\n        // login failed\n        throw new ConfigNotFoundError(`Medium 用户 ${user} 的 Cookie 无效或已过期`);\n    }\n\n    const urls = posts.items.map((data) => data.post.mediumUrl);\n\n    const parsedArticles = await Promise.all(urls.map((url) => parseArticle(ctx, url)));\n\n    return {\n        title: `${user} Medium Following Tag ${tag}`,\n        link: `https://medium.com/?tag=${tag}`,\n        item: parsedArticles,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/medium/tag.ts#L24-L60","documentation":"ConfigNotFoundError thrown by the Medium 'tag' route when config.medium.cookies[user] is undefined. The personalized tag feed requires an authenticated cookie, same mechanism as 363/365.","triggerScenarios":"Request to /medium/tag/:user/:tag with no cookie entry for that user in config — the lookup config.medium.cookies[user] returns undefined.","commonSituations":"Self-hosted RSSHub without MEDIUM_COOKIES; cookie key does not match the :user segment; using the public instance.","solutions":["Set MEDIUM_COOKIES env var keyed by the exact Medium username.","Copy the full Cookie header from a logged-in medium.com session.","Restart RSSHub to load the new config.","Match the cookie key to the :user path segment exactly (no @)."],"exampleFix":"// before\n// no MEDIUM_COOKIES in env\n\n// after\nMEDIUM_COOKIES=johndoe=sid%3A1%3A...","handlingStrategy":"validation","validationCode":"const cookie = config.medium.cookies?.[user];\nif (cookie === undefined) {\n    throw new ConfigNotFoundError(`Set MEDIUM_COOKIES for ${user}`);\n}","typeGuard":"function hasMediumCookie(user: string): boolean {\n    return Boolean(config.medium.cookies?.[user]);\n}","tryCatchPattern":null,"preventionTips":["Configure MEDIUM_COOKIES for every personalized Medium route.","Key the cookie map by the exact username.","Validate config at startup."],"tags":["medium","config","auth","cookie"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}