{"record":{"id":"5f30ddddaf4ba35c","repo":"DIYgod/RSSHub","slug":"please-check-the-config-of-notion-token","errorCode":null,"errorMessage":"Please check the config of NOTION_TOKEN","messagePattern":"Please check the config of NOTION_TOKEN","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"error","filePath":"lib/routes/notion/database.ts","lineNumber":172,"sourceCode":"\n        return {\n            title: `Notion - ${title}`,\n            link,\n            description,\n            image,\n            item: items,\n            allowEmpty: true,\n        };\n    } catch (error) {\n        logger.error(error);\n\n        if (isNotionClientError(error)) {\n            const { statusCode } = error as any;\n            if (statusCode === APIErrorCode.ObjectNotFound) {\n                throw new InvalidParameterError('The database is not exist');\n            }\n            if (statusCode === APIErrorCode.Unauthorized) {\n                throw new ConfigNotFoundError('Please check the config of NOTION_TOKEN');\n            }\n            ctx.throw(statusCode, 'Notion API Error');\n        } else {\n            ctx.throw(error);\n        }\n        return null;\n    }\n}\n\nfunction parseCustomQuery(queryString) {\n    try {\n        if (queryString) {\n            return JSON.parse(decodeURIComponent(queryString));\n        }\n    } catch {\n        logger.error('Query Parse Error');\n    }\n}","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/notion/database.ts#L154-L190","documentation":"ConfigNotFoundError thrown in the same try/catch when the Notion SDK error has statusCode APIErrorCode.Unauthorized. This means the request reached Notion but the NOTION_TOKEN was rejected — invalid, expired, revoked, or copy-pasted incorrectly. The route maps it to a config error pointing the operator at NOTION_TOKEN.","triggerScenarios":"NOTION_TOKEN is malformed, was revoked in Notion, belongs to a deleted integration, or has trailing whitespace from copy-paste. Distinct from 417 (token entirely missing) and 418 (token valid but lacks access to that specific DB).","commonSituations":"Token regenerated in Notion but RSSHub env not updated; token copied with leading/trailing whitespace; integration deleted; token from a different workspace.","solutions":["Regenerate the integration secret in notion.so/my-integrations and update NOTION_TOKEN in the RSSHub env.","Trim any whitespace/newlines from the token value in your env file.","Restart RSSHub so the new token is loaded.","Confirm the integration still exists and is in the same workspace as the target database."],"exampleFix":"// before\nif (statusCode === APIErrorCode.Unauthorized) {\n    throw new ConfigNotFoundError('Please check the config of NOTION_TOKEN');\n}\n\n// after — regenerate secret, then:\n//   export NOTION_TOKEN='secret_<freshly-generated>'","handlingStrategy":"try-catch","validationCode":"// Operator sanity check: token shape and freshness.\nfunction notionTokenLooksValid(token) {\n  return typeof token === 'string' && token.startsWith('secret_') && token.trim() === token;\n}","typeGuard":"const isNotionUnauthorized = (e: any): boolean =>\n  e?.code === 'unauthorized' || e?.status === 401 || e?.statusCode === APIErrorCode.Unauthorized;","tryCatchPattern":"try { await notion.databases.query({ database_id: id }); }\ncatch (e) {\n  if (isNotionUnauthorized(e)) {\n    // token invalid/expired/revoked — regenerate in Notion and update NOTION_TOKEN, then restart\n  } else if (isNotionNotFound(e)) {\n    // different root cause — see 418\n  } else throw e;\n}","preventionTips":["Trim whitespace from NOTION_TOKEN when pasting into env files.","When regenerating a secret in Notion, update RSSHub env and restart immediately.","Distinguish 401 (token bad) from 404 (DB not shared) — they need different fixes."],"tags":["notion","authentication","config","unauthorized"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}