{"record":{"id":"ad869d79cf3cd5f0","repo":"DIYgod/RSSHub","slug":"qweather-rss-is-disabled-due-to-the-lack-of-a-hre","errorCode":null,"errorMessage":"QWeather RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/zh/install/config#%E5%92%8C%E9%A3%8E%E5%A4%A9%E6%B0%94\">relevant config</a>","messagePattern":"QWeather RSS is disabled due to the lack of <a href=\"https://docs\\.rsshub\\.app/zh/install/config#%E5%92%8C%E9%A3%8E%E5%A4%A9%E6%B0%94\">relevant config</a>","errorType":"error_code","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"error","filePath":"lib/routes/qweather/3days.ts","lineNumber":42,"sourceCode":"                name: 'HEFENG_API_HOST',\n                description: 'This is required after 2026/01/01: https://blog.qweather.com/announce/public-api-domain-change-to-api-host/',\n            },\n        ],\n        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: '近三天天气',\n    maintainers: ['Rein-Ou', 'la3rence'],\n    handler,\n    description: '获取订阅近三天天气预报',\n};\n\nasync function handler(ctx) {\n    if (!config.hefeng.key || !config.hefeng.apiHost) {\n        throw new ConfigNotFoundError('QWeather RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/zh/install/config#%E5%92%8C%E9%A3%8E%E5%A4%A9%E6%B0%94\">relevant config</a>');\n    }\n\n    const WEATHER_API = `https://${config.hefeng.apiHost}/v7/weather/3d`;\n    const AIR_QUALITY_API = `https://${config.hefeng.apiHost}/v7/air/5d`;\n    const CIRY_LOOKUP_API = `https://${config.hefeng.apiHost}/geo/v2/city/lookup`;\n\n    const id = await cache.tryGet('qweather:' + ctx.req.param('location') + ':id', async () => {\n        const response = await got(`${CIRY_LOOKUP_API}?location=${ctx.req.param('location')}&key=${config.hefeng.key}`);\n        return response.data.location[0].id;\n    });\n    const weatherData = await cache.tryGet(\n        'qweather:' + ctx.req.param('location'),\n        async () => {\n            const response = await got(`${WEATHER_API}?key=${config.hefeng.key}&location=${id}`);\n            return response.data;\n        },\n        config.cache.contentExpire,\n        false","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/qweather/3days.ts#L24-L60","documentation":"The QWeather 3-day forecast route requires both `config.hefeng.key` (the API key) and `config.hefeng.apiHost` (the API host, e.g. devapi.qweather.com) to be set in the RSSHub instance configuration. If either is falsy, a `ConfigNotFoundError` is thrown before any cache lookup or HTTP call. This is the documented gate for any Hefeng/QWeather route — without credentials the upstream APIs return 403/401.","triggerScenarios":"A self-hosted RSSHub instance whose operator has not populated `HEFENG_KEY` and `HEFENG_APIHOST` env vars (or the equivalent in config). The check fires at the very top of `handler`, before the city-lookup cache call.","commonSituations":"Fresh deploy of RSSHub without environment variables set; operator copied only one of the two required values; key expired and was deleted from config.","solutions":["Set both environment variables on the RSSHub host: `HEFENG_KEY=<your key>` and `HEFENG_APIHOST=<devapi.qweather.com or api.qweather.com>`.","Restart the RSSHub process after editing config so it reloads `config.hefeng`.","If you cannot obtain a key, use the public rsshub.app instance only if its operator has configured QWeather — otherwise this route will remain unavailable."],"exampleFix":"// before\n# .env — missing or partial\nHEFENG_KEY=\n\n// after\n# .env\nHEFENG_KEY=abc123def456\nHEFENG_APIHOST=devapi.qweather.com","handlingStrategy":"validation","validationCode":"if (!config.hefeng?.key || !config.hefeng?.apiHost) {\n    return ctx.body('QWeather route requires HEFENG_KEY and HEFENG_APIHOST.', 503);\n}","typeGuard":"const hasHefengConfig = (c: typeof config): boolean =>\n    Boolean(c.hefeng?.key) && Boolean(c.hefeng?.apiHost);","tryCatchPattern":"try {\n    // handler body\n} catch (e) {\n    if (e instanceof ConfigNotFoundError) { /* surface a setup hint */ }\n    throw e;\n}","preventionTips":["Run a config sanity check at RSSHub startup that lists every route whose required config is missing.","Document HEFENG_KEY/HEFENG_APIHOST pairs in your deploy README.","Add a healthcheck endpoint that reports config.hefeng readiness."],"tags":["config-missing","env-vars","weather"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}