DIYgod/RSSHub · error · ConfigNotFoundError

QWeather RSS is disabled due to the lack of <a href="https:/

Error message

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>

What it means

The QWeather `now` (real-time) route gates on the same pair of config values as the 3-day route: `config.hefeng.key` and `config.hefeng.apiHost`. If either is absent the handler throws `ConfigNotFoundError` before any network call. Without the key the QWeather Now endpoint would reject every request.

Source

Thrown at lib/routes/qweather/now.ts:40

            {
                name: 'HEFENG_API_HOST',
                description: 'This is required after 2026/01/01: https://blog.qweather.com/announce/public-api-domain-change-to-api-host/',
            },
        ],
        requirePuppeteer: false,
        antiCrawler: false,
        supportBT: false,
        supportPodcast: false,
        supportScihub: false,
    },
    name: '实时天气',
    maintainers: ['Rein-Ou'],
    handler,
};

async function handler(ctx) {
    if (!config.hefeng.key || !config.hefeng.apiHost) {
        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>');
    }
    const NOW_WEATHER_API = `https://${config.hefeng.apiHost}/v7/weather/now`;
    const CIRY_LOOKUP_API = `https://${config.hefeng.apiHost}/geo/v2/city/lookup`;

    const id = await cache.tryGet('qweather:' + ctx.req.param('location') + ':id', async () => {
        const response = await got(`${CIRY_LOOKUP_API}?location=${ctx.req.param('location')}&key=${config.hefeng.key}`);
        const data = response.data.location.map((loc) => loc);
        return data[0].id;
    });
    const requestUrl = `${NOW_WEATHER_API}?key=${config.hefeng.key}&location=${id}`;
    const responseData = await cache.tryGet(
        'qweather:' + ctx.req.param('location') + ':now',
        async () => {
            const response = await got(requestUrl);
            return response.data;
        },
        3600, // second
        false

View on GitHub (pinned to bed535e087)

Solutions

  1. Provide both `HEFENG_KEY` and `HEFENG_APIHOST` in the RSSHub configuration and restart.
  2. Confirm the key is valid by calling the QWeather API directly with curl; an invalid key surfaces as a 401/403 from the upstream rather than this error.
  3. Use a documented apiHost (`devapi.qweather.com` for free tier, `api.qweather.com` for paid).

Example fix

// before
HEFENG_KEY=
HEFENG_APIHOST=

// after
HEFENG_KEY=<valid key>
HEFENG_APIHOST=devapi.qweather.com
Defensive patterns

Strategy: validation

Validate before calling

if (!config.hefeng?.key || !config.hefeng?.apiHost) {
    return ctx.body('QWeather now route requires HEFENG_KEY and HEFENG_APIHOST.', 503);
}

Type guard

const hasHefengConfig = (c: typeof config): boolean => Boolean(c.hefeng?.key && c.hefeng?.apiHost);

Try / catch

try { /* handler */ } catch (e) { if (e instanceof ConfigNotFoundError) { /* hint */ } throw e; }

Prevention

When it happens

Trigger: Same as 3days: a route request to /qweather/now/:location on an instance where Hefeng config is incomplete.

Common situations: Instance upgraded without re-setting env vars; key rotated but only the new one (not apiHost) was re-added; Docker image run without `-e HEFENG_KEY=...`.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/0a3ea015fb772203. Report an issue: GitHub.