DIYgod/RSSHub · error · ConfigNotFoundError

Please check the config of NOTION_TOKEN

Error message

Please check the config of NOTION_TOKEN

What it means

ConfigNotFoundError thrown in the same try/catch when the Notion SDK error has statusCode APIErrorCode.Unauthorized. This means the request reached Notion but the NOTION_TOKEN was rejected — invalid, expired, revoked, or copy-pasted incorrectly. The route maps it to a config error pointing the operator at NOTION_TOKEN.

Source

Thrown at lib/routes/notion/database.ts:172

        return {
            title: `Notion - ${title}`,
            link,
            description,
            image,
            item: items,
            allowEmpty: true,
        };
    } catch (error) {
        logger.error(error);

        if (isNotionClientError(error)) {
            const { statusCode } = error as any;
            if (statusCode === APIErrorCode.ObjectNotFound) {
                throw new InvalidParameterError('The database is not exist');
            }
            if (statusCode === APIErrorCode.Unauthorized) {
                throw new ConfigNotFoundError('Please check the config of NOTION_TOKEN');
            }
            ctx.throw(statusCode, 'Notion API Error');
        } else {
            ctx.throw(error);
        }
        return null;
    }
}

function parseCustomQuery(queryString) {
    try {
        if (queryString) {
            return JSON.parse(decodeURIComponent(queryString));
        }
    } catch {
        logger.error('Query Parse Error');
    }
}

View on GitHub (pinned to bed535e087)

Solutions

  1. Regenerate the integration secret in notion.so/my-integrations and update NOTION_TOKEN in the RSSHub env.
  2. Trim any whitespace/newlines from the token value in your env file.
  3. Restart RSSHub so the new token is loaded.
  4. Confirm the integration still exists and is in the same workspace as the target database.

Example fix

// before
if (statusCode === APIErrorCode.Unauthorized) {
    throw new ConfigNotFoundError('Please check the config of NOTION_TOKEN');
}

// after — regenerate secret, then:
//   export NOTION_TOKEN='secret_<freshly-generated>'
Defensive patterns

Strategy: try-catch

Validate before calling

// Operator sanity check: token shape and freshness.
function notionTokenLooksValid(token) {
  return typeof token === 'string' && token.startsWith('secret_') && token.trim() === token;
}

Type guard

const isNotionUnauthorized = (e: any): boolean =>
  e?.code === 'unauthorized' || e?.status === 401 || e?.statusCode === APIErrorCode.Unauthorized;

Try / catch

try { await notion.databases.query({ database_id: id }); }
catch (e) {
  if (isNotionUnauthorized(e)) {
    // token invalid/expired/revoked — regenerate in Notion and update NOTION_TOKEN, then restart
  } else if (isNotionNotFound(e)) {
    // different root cause — see 418
  } else throw e;
}

Prevention

When it happens

Trigger: NOTION_TOKEN is malformed, was revoked in Notion, belongs to a deleted integration, or has trailing whitespace from copy-paste. Distinct from 417 (token entirely missing) and 418 (token valid but lacks access to that specific DB).

Common situations: Token regenerated in Notion but RSSHub env not updated; token copied with leading/trailing whitespace; integration deleted; token from a different workspace.

Related errors


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