{"record":{"id":"44b145be8d7e09fb","repo":"DIYgod/RSSHub","slug":"pixiv-not-login-44b145","errorCode":null,"errorMessage":"pixiv not login","messagePattern":"pixiv not login","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":null,"severity":"error","filePath":"lib/routes/pixiv/novel-api/series/nsfw.ts","lineNumber":40,"sourceCode":"            series_id: seriesId,\n            last_order: offset,\n        }),\n    });\n    return rsp.data as AppNovelSeries;\n}\n\nexport async function getNSFWSeriesNovels(seriesId: string, limit: number = 10): Promise<SeriesFeed> {\n    if (limit > 30) {\n        limit = 30;\n    }\n\n    if (!config.pixiv || !config.pixiv.refreshToken) {\n        throw new ConfigNotFoundError('This user is an R18 creator, PIXIV_REFRESHTOKEN is required.\\npixiv RSS is disabled due to the lack of relevant config.\\n該用戶爲 R18 創作者，需要 PIXIV_REFRESHTOKEN。');\n    }\n\n    const token = await getToken();\n    if (!token) {\n        throw new ConfigNotFoundError('pixiv not login');\n    }\n\n    const seriesResponse = await got(`${baseUrl}/ajax/novel/series/${seriesId}`, {\n        headers: {\n            ...maskHeader,\n            Authorization: 'Bearer ' + token,\n        },\n    });\n    const seriesData = seriesResponse.data as SeriesDetail;\n\n    let offset = seriesData.body.total - limit;\n    if (offset < 0) {\n        offset = 0;\n    }\n    const appSeriesData = await getNovelSeries(seriesId, offset, token);\n\n    const items = await Promise.all(\n        appSeriesData.novels.map(async (novel) => {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/pixiv/novel-api/series/nsfw.ts#L22-L58","documentation":"Thrown by getNSFWSeriesNovels after getToken() returns a falsy value. getToken() refreshes the pixiv access token by POSTing to oauth.secure.pixiv.net/auth.token; if that response lacks data.access_token the module-level token variable stays null and this fires. It means a refreshToken WAS configured (the previous guard passed) but the OAuth refresh itself failed.","triggerScenarios":"PIXIV_REFRESHTOKEN is present but invalid, expired, revoked, or belongs to a different client; the oauth endpoint rejected the grant; the refresh call was blocked at the network layer (pixiv blocks many CN IPs); the response was cached empty under key 'pixiv:accessToken' for up to 3600s.","commonSituations":"Refresh token expired (they are single-use / time-limited); RSSHub server IP region-blocked by pixiv; a stale empty token cached under 'pixiv:accessToken' for an hour; token copied incorrectly with trailing whitespace.","solutions":["Re-obtain a fresh PIXIV_REFRESHTOKEN from a working pixiv login flow and replace the old value.","Ensure the RSSHub host can reach oauth.secure.pixiv.net (route through a proxy/VPN if the server is in a blocked region).","Flush the cached access token (key 'pixiv:accessToken') so the next call re-attempts the refresh instead of returning the cached null.","Inspect logs around the refreshToken POST for the pixiv OAuth error body."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { getToken } from './token';\nasync function ensurePixivToken(): Promise<string | null> {\n  const token = await getToken();\n  return token || null;\n}\n// call before the NSFW series request:\nconst token = await ensurePixivToken();\nif (!token) {\n  // handle expired/invalid refresh token (regenerate PIXIV_REFRESHTOKEN)","typeGuard":"const isUsableToken = (t: unknown): t is string => typeof t === 'string' && t.length > 0;","tryCatchPattern":"try {\n  const token = await getToken();\n  if (!token) throw new ConfigNotFoundError('pixiv not login');\n} catch (e) {\n  if (e instanceof ConfigNotFoundError) {\n    // refresh failed: clear cached 'pixiv:accessToken', prompt token regeneration\n  }\n}","preventionTips":["Treat getToken() returning null as a credentials problem, not a transient one; do not blind-retry.","Invalidate the 'pixiv:accessToken' cache key on failure so the next attempt re-refreshes.","Monitor the pixiv oauth response in logs to catch token expiry early."],"tags":["pixiv","authentication","oauth","token","nsfw"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}