DIYgod/RSSHub · error · ConfigNotFoundError

nhentai RSS with torrents is disabled due to the lack of <a

Error message

nhentai RSS with torrents is disabled due to the lack of <a href="https://docs.rsshub.app/deploy/config#route-specific-configurations">relevant config</a>

What it means

A ConfigNotFoundError raised by getTorrents when the nhentai torrent feature is requested but the deployment has not supplied nhentai credentials. RSSHub uses ConfigNotFoundError specifically to signal a missing server-side configuration (env: NHENTAI_USERNAME / NHENTAI_PASSWORD), distinct from invalid user input, so the operator (not the subscriber) must act. The HTML link in the message points operators to the route-specific config docs.

Source

Thrown at lib/routes/nhentai/util.tsx:106

        }
        throw error;
    }
};

const getSimple = async (url) => {
    const data = await fetchPage(url);
    const $ = load(data);

    return $('.gallery a.cover')
        .toArray()
        .map((ele) => parseSimpleDetail($(ele)));
};

const getDetails = (cache, simples, limit) => Promise.all(simples.slice(0, limit).map((simple) => cache.tryGet(simple.link, () => getDetail(simple))));

const getTorrents = async (cache, simples, limit) => {
    if (!config.nhentai || !config.nhentai.username || !config.nhentai.password) {
        throw new ConfigNotFoundError('nhentai RSS with torrents is disabled due to the lack of <a href="https://docs.rsshub.app/deploy/config#route-specific-configurations">relevant config</a>');
    }
    const cookie = await getCookie(config.nhentai.username, config.nhentai.password, cache);
    if (!cookie) {
        throw new ConfigNotFoundError('Invalid username (or email) or password for nhentai torrent download');
    }
    return getTorrentWithCookie(cache, simples, cookie, limit);
};
const getTorrentWithCookie = (cache, simples, cookie, limit) => Promise.all(simples.slice(0, limit).map((simple) => cache.tryGet(simple.link + 'download', () => getTorrent(simple, cookie))));

const parseSimpleDetail = ($ele) => {
    const link = new URL($ele.attr('href'), baseUrl).href;
    const thumb = $ele.children('img');
    const thumbSrc = thumb.attr('data-src') || thumb.attr('src');
    const highResoThumbSrc = thumbSrc
        .replace('thumb', '1')
        .replace(/t(\d+)\.nhentai\.net/, 'i$1.nhentai.net')
        .replace('.webp.webp', '.webp');
    return {

View on GitHub (pinned to bed535e087)

Solutions

  1. Set NHENTAI_USERNAME and NHENTAI_PASSWORD in the RSSHub environment (.env / container env) per https://docs.rsshub.app/deploy/config#route-specific-configurations and restart.
  2. Verify the keys are read under config.nhentai.* by the config loader (the config namespace must be 'nhentai').
  3. If the feature is not needed, stop subscribing to the torrent-producing route variant so getTorrents is never invoked.

Example fix

// before
if (!config.nhentai || !config.nhentai.username || !config.nhentai.password) {
    throw new ConfigNotFoundError('nhentai RSS with torrents is disabled ...');
}

// after — no code change; fix is environment-side:
// .env
// NHENTAI_USERNAME=your_username
// NHENTAI_PASSWORD=your_password
Defensive patterns

Strategy: validation

Validate before calling

// Check config readiness before invoking any torrent-producing nhentai route.
function nhentaiConfigured(): boolean {
    return Boolean(config.nhentai?.username && config.nhentai?.password);
}
if (routeNeedsTorrents && !nhentaiConfigured()) {
    // skip torrent enrichment, return the non-torrent feed instead of throwing
}

Type guard

const hasNhentaiCreds = (c: typeof config): c is typeof config & { nhentai: { username: string; password: string } } =>
    Boolean(c.nhentai && c.nhentai.username && c.nhentai.password);

Try / catch

import ConfigNotFoundError from '@/errors/types/config-not-found';
try {
    items = await getTorrents(cache, simples, limit);
} catch (e) {
    if (e instanceof ConfigNotFoundError) {
        // feature intentionally disabled — return the feed without torrent enclosures
        items = await getDetails(cache, simples, limit);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling a nhentai route with torrent/enclosure output enabled (e.g. the torrent download path) while config.nhentai is undefined or lacks username/password. Concretely, the check `!config.nhentai || !config.nhentai.username || !config.nhentai.password` short-circuits true.

Common situations: Self-hosted RSSHub deployed without setting NHENTAI_USERNAME/NHENTAI_PASSWORD in the environment; the credentials were removed during a config cleanup; the route is being exercised on a public rsshub.app instance where the feature is intentionally disabled.

Related errors


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