{"record":{"id":"c22c4e8738095f02","repo":"DIYgod/RSSHub","slug":"notion-rss-is-disabled-due-to-the-lack-of-notion-t","errorCode":null,"errorMessage":"Notion RSS is disabled due to the lack of NOTION_TOKEN(<a href=\"https://docs.rsshub.app/deploy/config#route-specific-configurations\">relevant config</a>)","messagePattern":"Notion RSS is disabled due to the lack of NOTION_TOKEN\\(<a href=\"https://docs\\.rsshub\\.app/deploy/config#route-specific-configurations\">relevant config</a>\\)","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"error","filePath":"lib/routes/notion/database.ts","lineNumber":62,"sourceCode":"    name: 'Database',\n    maintainers: ['curly210102'],\n    handler,\n    description: `There is an optional query parameter called \\`properties=\\` that can be used to customize field mapping. There are three built-in fields: author, pubTime and link, which can be used to add additional information.\n\nFor example, if you have set up three properties in your database - \"Publish Time\", \"Author\", and \"Original Article Link\" - then execute the following JavaScript code to get the result for the properties parameter.\n\n\\`\\`\\`js\nencodeURIComponent(JSON.stringify({\"pubTime\": \"Publish Time\", \"author\": \"Author\", \"link\": \"Original Article Link\"}))\n\\`\\`\\`\n\nThere is an optional query parameter called \\`query=\\` that can be used to customize the search rules for your database, such as custom sorting and filtering rules.\n\nplease refer to the [Notion API documentation](https://developers.notion.com/reference/post-database-query) and execute \\`encodeURIComponent(JSON.stringify(custom rules))\\` to provide the query parameter.`,\n};\n\nasync function handler(ctx) {\n    if (!config.notion.key) {\n        throw new ConfigNotFoundError('Notion RSS is disabled due to the lack of NOTION_TOKEN(<a href=\"https://docs.rsshub.app/deploy/config#route-specific-configurations\">relevant config</a>)');\n    }\n\n    const databaseId = ctx.req.param('databaseId');\n    const notion_api_key = config.notion.key;\n\n    const notion = new Client({\n        auth: notion_api_key,\n    });\n\n    try {\n        // Query database basic info\n        const database = (await notion.databases.retrieve({ database_id: databaseId })) as any;\n        const title = database.title[0]?.plain_text;\n        const description = database.description[0]?.plain_text;\n        const link = database.url;\n        const image = database.cover?.external.url ?? database.icon?.emoji;\n\n        // List pages under the database","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/notion/database.ts#L44-L80","documentation":"ConfigNotFoundError thrown by the Notion database route when config.notion.key is falsy. The route uses the official @notionhq/client SDK with an auth token (NOTION_TOKEN); without it the SDK cannot call the Notion API, so the route refuses to run and links to the deploy config docs.","triggerScenarios":"Calling /notion/database/:databaseId without NOTION_TOKEN (config.notion.key) set. The route declares NOTION_TOKEN under features.requireConfig, so this guard is the runtime enforcement.","commonSituations":"Fresh RSSHub deploy without NOTION_TOKEN; env var cleared during a rebuild; token was revoked in Notion and removed from config; self-hosted instance never configured for Notion.","solutions":["Create an internal integration at notion.so/my-integrations, copy the secret, and set NOTION_TOKEN (config.notion.key) in the RSSHub environment.","In Notion, share the target database with the integration (Open database → ••• → Connections → add the integration) — the token alone is not enough.","Restart RSSHub after setting the env var so config is re-read.","Verify with a single database you know is shared with the integration."],"exampleFix":"// before\nif (!config.notion.key) {\n    throw new ConfigNotFoundError('Notion RSS is disabled ...');\n}\n\n// after — set env: export NOTION_TOKEN='secret_xxx' and share the DB with the integration","handlingStrategy":"validation","validationCode":"if (!process.env.NOTION_TOKEN) {\n  console.error('NOTION_TOKEN not set — /notion/database/* will throw ConfigNotFoundError.');\n}","typeGuard":"const isNotionConfigured = (): boolean =>\n  Boolean(config.notion && typeof config.notion.key === 'string' && config.notion.key.startsWith('secret_'));","tryCatchPattern":"try { await fetch('/notion/database/<id>'); }\ncatch (e) {\n  if (/NOTION_TOKEN/.test(e.message)) { /* operator config issue, no retry */ }\n  else throw e;\n}","preventionTips":["Create the integration at notion.so/my-integrations and copy the secret into NOTION_TOKEN.","Share each target database with the integration (Connections) — the token alone is insufficient.","Restart RSSHub after setting the env var."],"tags":["config","authentication","notion","required-config"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}