{"record":{"id":"2671836badb6da76","repo":"DIYgod/RSSHub","slug":"tumblr-rss-is-disabled-due-to-the-lack-of-a-href","errorCode":null,"errorMessage":"Tumblr RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/deploy/config#route-specific-configurations\">relevant config</a>","messagePattern":"Tumblr RSS is disabled due to the lack of <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/tumblr/posts.ts","lineNumber":50,"sourceCode":"            },\n        ],\n        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: 'Posts',\n    maintainers: ['Rakambda', 'PolarisStarnor'],\n    description: `::: tip\nTumblr provides official RSS feeds for non \"dashboard only\" blogs, for instance [https://biketouring-nearby.tumblr.com](https://biketouring-nearby.tumblr.com/rss).\n:::`,\n    handler,\n};\n\nasync function handler(ctx: Context): Promise<Data> {\n    if (!config.tumblr || !config.tumblr.clientId) {\n        throw new ConfigNotFoundError('Tumblr RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/deploy/config#route-specific-configurations\">relevant config</a>');\n    }\n\n    const blogIdentifier = ctx.req.param('blog');\n    const limit = fallback(undefined, queryToInteger(ctx.req.query('limit')), 20);\n\n    const response = await got.get(`https://api.tumblr.com/v2/blog/${blogIdentifier}/posts`, {\n        searchParams: {\n            api_key: utils.generateAuthParams(),\n            limit,\n        },\n        headers: await utils.generateAuthHeaders(),\n    });\n\n    const blog = response.data.response.blog;\n    const posts = response.data.response.posts.map((post: any) => utils.processPost(post));\n\n    return {\n        title: `Tumblr - ${blogIdentifier} - Posts`,","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/tumblr/posts.ts#L32-L68","documentation":"ConfigNotFoundError from the Tumblr Posts route: it requires `config.tumblr.clientId` (and the broader `config.tumblr` object) to call the Tumblr v2 API. If either is missing the handler aborts before requesting `api.tumblr.com/v2/blog/{blog}/posts`.","triggerScenarios":"`config.tumblr` is undefined or `config.tumblr.clientId` is falsy on line 51, so line 52 throws. The route depends on a registered Tumblr OAuth client id/secret.","commonSituations":"Self-hosted RSSHub without `TUMBLR_CLIENT_ID`/`TUMBLR_CLIENT_SECRET` env vars; the consumer key was revoked by Tumblr; the config object key was misspelled.","solutions":["Register an application at https://www.tumblr.com/oauth/apps to obtain a consumer key.","Set `TUMBLR_CLIENT_ID` and `TUMBLR_CLIENT_SECRET` in your RSSHub environment and restart.","Confirm `config.tumblr.clientId` resolves after restart by logging the value's presence (not the value)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!config.tumblr?.clientId) { throw new ConfigNotFoundError('Set TUMBLR_CLIENT_ID/TUMBLR_CLIENT_SECRET before enabling Tumblr routes'); }","typeGuard":"const hasTumblrConfig = (c: unknown): c is { clientId: string } => typeof c === 'object' && c !== null && typeof (c as any).clientId === 'string';","tryCatchPattern":null,"preventionTips":["Register the Tumblr OAuth app once and store credentials in a secret manager","Mark the route as requireConfig so the registry reflects the dependency","Restart RSSHub after adding credentials"],"tags":["config","oauth","tumblr","authentication","config-not-found"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}