{"record":{"id":"b68d3a4a2c47d6c9","repo":"facebook/docusaurus","slug":"unexpected-color-mode-colormode","errorCode":null,"errorMessage":"unexpected color mode ${colorMode}","messagePattern":"unexpected color mode (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/docusaurus-theme-classic/src/theme/ColorModeToggle/index.tsx","lineNumber":39,"sourceCode":"function getNextColorMode(\n  colorMode: ColorMode | null,\n  respectPrefersColorScheme: boolean,\n) {\n  // 2-value transition\n  if (!respectPrefersColorScheme) {\n    return colorMode === 'dark' ? 'light' : 'dark';\n  }\n\n  // 3-value transition\n  switch (colorMode) {\n    case null:\n      return 'light';\n    case 'light':\n      return 'dark';\n    case 'dark':\n      return null;\n    default:\n      throw new Error(`unexpected color mode ${colorMode}`);\n  }\n}\n\nfunction getColorModeLabel(colorMode: ColorMode | null): string {\n  switch (colorMode) {\n    case null:\n      return translate({\n        message: 'system mode',\n        id: 'theme.colorToggle.ariaLabel.mode.system',\n        description: 'The name for the system color mode',\n      });\n    case 'light':\n      return translate({\n        message: 'light mode',\n        id: 'theme.colorToggle.ariaLabel.mode.light',\n        description: 'The name for the light color mode',\n      });\n    case 'dark':","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/index.tsx#L21-L57","documentation":"Thrown by `ColorModeToggle`'s 3-value cycle helper when `colorMode` is not one of `null`, `'light'`, or `'dark'`. The function cycles the toggle button through system → light → dark → system, so any other value is a programming error. `ColorMode` is typed as `'light' | 'dark'` and the third state `null` represents 'follow system'.","triggerScenarios":"The cycle function receives a `colorMode` that has been corrupted (e.g. an arbitrary string from a malformed `localStorage` entry, a browser extension, or a hand-edited persisted state). It can also fire if a swizzled toggle passes through an unvalidated value.","commonSituations":"A user has manually edited `theme-color-scheme`/localStorage entries; a browser extension injects a value; a swizzled `ColorModeToggle` reads from a non-standard source; a stale persisted state from an older Docusaurus version survives an upgrade.","solutions":["Clear the site's localStorage (key `theme` / `docusaurus-color-mode`) and reload to reset to a valid value.","If you swizzled the toggle, validate/sanitize the incoming `colorMode` with `coerceToColorMode` before passing it into the cycle function.","Ensure no custom code writes arbitrary strings into the color-mode storage key."],"exampleFix":"// before\nconst next = cycleThreeValue(colorMode); // throws on garbage\n// after\nimport {coerceToColorMode} from '@docusaurus/ThemeCommon';\nconst safe = coerceToColorMode(rawColorMode); // 'light' | 'dark'\nconst next = cycleThreeValue(safe);","handlingStrategy":"validation","validationCode":"import {coerceToColorMode} from '@docusaurus/ThemeCommon';\n// coerceToColorMode normalizes arbitrary input to 'light'|'dark'\nconst safe = coerceToColorMode(rawStored);\nconst next = cycleThreeValue(safe === lastLightOrDark ? null : safe); // only feed valid values","typeGuard":"type ColorMode = 'light' | 'dark';\nfunction isColorMode(v: unknown): v is ColorMode {\n  return v === 'light' || v === 'dark';\n}","tryCatchPattern":null,"preventionTips":["Never write arbitrary strings to the color-mode localStorage key.","Sanitize persisted state on read with `coerceToColorMode`.","Keep swizzled toggle logic identical to upstream's three-state switch."],"tags":["react","color-mode","switch-exhaustiveness","theme-classic"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}