{"record":{"id":"91bc273f934270a7","repo":"DIYgod/RSSHub","slug":"medium-user-cookie-91bc27","errorCode":null,"errorMessage":"Medium 用户 ${user} 的 Cookie 无效或已过期","messagePattern":"Medium 用户 (.+?) 的 Cookie 无效或已过期","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":null,"severity":"error","filePath":"lib/routes/medium/following.ts","lineNumber":47,"sourceCode":"    description: `::: 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\n    const cookie = config.medium.cookies[user];\n    if (cookie === undefined) {\n        throw new ConfigNotFoundError(`缺少 Medium 用户 ${user} 登录后的 Cookie 值`);\n    }\n\n    const posts = await getFollowingFeedQuery(user, 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`,\n        link: 'https://medium.com/?feed=following',\n        item: parsedArticles,\n    };\n}\n","sourceCodeStart":29,"sourceCodeEnd":60,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/medium/following.ts#L29-L60","documentation":"ConfigNotFoundError thrown when getFollowingFeedQuery returns a falsy result — meaning the Medium GraphQL following endpoint rejected the supplied cookie. The cookie exists in config but is no longer valid (expired or revoked), so Medium's API returns an empty/error response.","triggerScenarios":"config.medium.cookies[user] is set (so 363 is skipped), but getFollowingFeedQuery(user, cookie) resolves to a falsy value. This is Medium's API signaling authentication failure without throwing — the cookie's session has lapsed.","commonSituations":"Cookie older than ~1–2 weeks (Medium sessions expire); user logged out of all devices invalidating the sid; cookie copied incompletely (missing sub-cookies); Medium rotated its session token format.","solutions":["Re-log into medium.com and recopy the full Cookie header value into config.","Verify the cookie includes the 'sid' token and any 'cf_' Cloudflare cookies.","Update MEDIUM_COOKIES and restart RSSHub.","If it still fails, the account may be flagged — try with a fresh account/cookie."],"exampleFix":"// before — stale cookie in config\nMEDIUM_COOKIES=johndoe=sid%3Aold_expired_token\n\n// after — fresh cookie from browser DevTools\nMEDIUM_COOKIES=johndoe=sid%3A1%3A...new...","handlingStrategy":"try-catch","validationCode":"// Pre-flight: hit a cheap Medium auth-check endpoint with the cookie\n// before calling the heavy following feed.","typeGuard":null,"tryCatchPattern":"try {\n    const posts = await getFollowingFeedQuery(user, cookie);\n    if (!posts) throw new ConfigNotFoundError('Medium cookie expired — refresh it');\n} catch (e) {\n    // alert operator to refresh MEDIUM_COOKIES\n    throw e;\n}","preventionTips":["Schedule periodic cookie refreshes — Medium sessions last ~1-2 weeks.","Monitor feed health and alert on this specific error.","Automate cookie capture via a headless browser if operating at scale."],"tags":["medium","auth","cookie","expired"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}