{"record":{"id":"556c98327efde855","repo":"DIYgod/RSSHub","slug":"mixi2-auth-token-and-mixi2-auth-key-are-required","errorCode":null,"errorMessage":"MIXI2_AUTH_TOKEN and MIXI2_AUTH_KEY are required","messagePattern":"MIXI2_AUTH_TOKEN and MIXI2_AUTH_KEY are required","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"error","filePath":"lib/routes/mixi2/utils.ts","lineNumber":13,"sourceCode":"import type { Persona, Post } from 'mixi2';\nimport { Category, MixiClient } from 'mixi2';\n\nimport { config } from '@/config';\nimport ConfigNotFoundError from '@/errors/types/config-not-found';\nimport ofetch from '@/utils/ofetch';\nimport { parseDate } from '@/utils/parse-date';\n\nexport function getClient() {\n    const { authToken, authKey } = config.mixi2;\n\n    if (!authToken || !authKey) {\n        throw new ConfigNotFoundError('MIXI2_AUTH_TOKEN and MIXI2_AUTH_KEY are required');\n    }\n\n    return new MixiClient(`auth_token=${authToken}`, authKey, {\n        httpAdapter: ofetch,\n    });\n}\n\nexport function parsePost(post: Post) {\n    let description = post.text ? `<p>${post.text}</p>` : '';\n\n    const medias = post.medias ?? [];\n    for (const media of medias) {\n        if (media.category === Category.CATEGORY_POST_IMAGE) {\n            description += `<img src=\"${media.postImage?.largeImageUrl ?? media.postImage?.smallImageUrl}\"${media.description ? `alt=\"${media.description}\"` : ''} />`;\n        } else if (media.category === Category.CATEGORY_POST_VIDEO) {\n            description += `<img src=\"${media.postVideo?.previewImageUrl}\" alt=\"${media.description}\" />`;\n        }\n    }","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mixi2/utils.ts#L1-L31","documentation":"Thrown as ConfigNotFoundError by getClient() in the mixi2 utils — the shared factory that builds a MixiClient for all mixi2 routes. It requires BOTH config.mixi2.authToken and config.mixi2.authKey; if either is falsy the route is disabled. These credentials authenticate against mixi's private API (the auth_token is a cookie-style token and auth_key a signing key used by the mixi2 SDK).","triggerScenarios":"Any mixi2 route is hit while MIXI2_AUTH_TOKEN or MIXI2_AUTH_KEY is unset. getClient() reads config.mixi2 and throws before constructing MixiClient. Because getClient is called inside each handler, the error appears on the first request to any mixi2 feed.","commonSituations":"Fresh deploy without the mixi2 secrets; only one of the two vars set; vars named with wrong case in the environment; tokens rotated by mixi and not refreshed.","solutions":["Obtain the auth_token and auth_key for a mixi account (capture from a logged-in mixi.social session per the mixi2 SDK docs) and set both MIXI2_AUTH_TOKEN and MIXI2_AUTH_KEY in RSSHub's environment.","Restart RSSHub and confirm both vars are present in the process env.","If tokens expired, re-capture a fresh session and update both values.","Note this route is effectively self-host only — the credentials are per-account."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const { authToken, authKey } = config.mixi2;\nif (!authToken || !authKey) {\n    throw new ConfigNotFoundError('Set both MIXI2_AUTH_TOKEN and MIXI2_AUTH_KEY to enable mixi2 routes.');\n}","typeGuard":"function hasMixi2Config(c: any): c is { mixi2: { authToken: string; authKey: string } } {\n    return typeof c?.mixi2?.authToken === 'string' && typeof c?.mixi2?.authKey === 'string' && c.mixi2.authToken.length > 0 && c.mixi2.authKey.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Set both secrets together; one without the other always fails.","Rotate and refresh tokens when mixi sessions expire.","Run a startup probe that constructs a MixiClient and makes a trivial call to fail fast on bad credentials."],"tags":["missing-config","authentication","api-token","mixi2","self-hosted"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}