DIYgod/RSSHub · error · ConfigNotFoundError

Missing access token for Misskey API. Please set `MISSKEY_AC

Error message

Missing access token for Misskey API. Please set `MISSKEY_ACCESS_TOKEN` environment variable.

What it means

Thrown as ConfigNotFoundError by the Misskey 'home timeline' route when config.misskey.accessToken is falsy. This route is self-host only — it returns the authenticated user's personal home timeline via POST https://<site>/api/notes/timeline, which requires a user access token sent as Authorization: Bearer <token>. No token means the feed is disabled.

Source

Thrown at lib/routes/misskey/home-timeline.ts:69

        supportScihub: false,
    },
    radar: [
        {
            source: ['misskey.io'],
        },
    ],
    name: 'Home Timeline',
    maintainers: ['HanaokaYuzu'],
    handler,
    description: `::: warning
This route is only available for self-hosted instances.
:::`,
};

async function handler(ctx) {
    const access_token = config.misskey.accessToken;
    if (!access_token) {
        throw new ConfigNotFoundError('Missing access token for Misskey API. Please set `MISSKEY_ACCESS_TOKEN` environment variable.');
    }

    const site = ctx.req.param('site');
    if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) {
        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
    }

    // docs on: https://misskey.io/api-doc#tag/notes/operation/notes___timeline
    const url = `https://${site}/api/notes/timeline`;
    const routeParams = querystring.parse(ctx.req.param('routeParams'));
    const response = await got({
        method: 'post',
        url,
        headers: {
            Authorization: `Bearer ${access_token}`,
        },
        json: {
            limit: Number(routeParams.limit ?? 10),

View on GitHub (pinned to bed535e087)

Solutions

  1. Generate a Misskey access token (Settings → API → Generate access token, with the 'read' scope on notes/timeline) and set it as MISSKEY_ACCESS_TOKEN in RSSHub's environment.
  2. Restart RSSHub and confirm the var is present in the process environment.
  3. Verify the token works directly: `curl -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' -d '{"limit":10}' https://<site>/api/notes/timeline`.
  4. Ensure :site is on the allow-list or ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true, otherwise you will next hit error 387.
Defensive patterns

Strategy: validation

Validate before calling

const access_token = config.misskey.accessToken;
if (!access_token) {
    throw new ConfigNotFoundError('Set MISSKEY_ACCESS_TOKEN (a Misskey API token with read scope) to enable the home timeline.');
}

Type guard

function hasMisskeyToken(c: any): boolean {
    return typeof c?.misskey?.accessToken === 'string' && c.misskey.accessToken.length > 0;
}

Prevention

When it happens

Trigger: Any request to /misskey/home-timeline/:site while MISSKEY_ACCESS_TOKEN is unset. The token check runs before the host allow-list check, so even an allowed site throws here if the token is missing.

Common situations: A self-hoster who enabled the route's instance but never generated a Misskey access token; MISSKEY_ACCESS_TOKEN set under a different name/case; the token was committed-then-rotated and the env wasn't updated.

Related errors


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