{"record":{"id":"e840395973f745b3","repo":"mantinedev/mantine","slug":"invalid-primary-shade-error","errorCode":null,"errorMessage":"INVALID_PRIMARY_SHADE_ERROR","messagePattern":"INVALID_PRIMARY_SHADE_ERROR","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@mantine/core/src/core/MantineProvider/merge-mantine-theme/merge-mantine-theme.ts","lineNumber":28,"sourceCode":"function isValidPrimaryShade(shade: number) {\n  if (shade < 0 || shade > 9) {\n    return false;\n  }\n\n  return parseInt(shade.toString(), 10) === shade;\n}\n\nexport function validateMantineTheme(theme: MantineTheme): asserts theme is MantineTheme {\n  if (!(theme.primaryColor in theme.colors)) {\n    throw new Error(INVALID_PRIMARY_COLOR_ERROR);\n  }\n\n  if (typeof theme.primaryShade === 'object') {\n    if (\n      !isValidPrimaryShade(theme.primaryShade.dark) ||\n      !isValidPrimaryShade(theme.primaryShade.light)\n    ) {\n      throw new Error(INVALID_PRIMARY_SHADE_ERROR);\n    }\n  }\n\n  if (typeof theme.primaryShade === 'number' && !isValidPrimaryShade(theme.primaryShade)) {\n    throw new Error(INVALID_PRIMARY_SHADE_ERROR);\n  }\n}\n\nexport function mergeMantineTheme(\n  currentTheme: MantineTheme,\n  themeOverride?: MantineThemeOverride\n) {\n  if (!themeOverride) {\n    validateMantineTheme(currentTheme);\n    return currentTheme;\n  }\n\n  const result = deepMerge(currentTheme, themeOverride);","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/mantinedev/mantine/blob/8a284e2c2c53a9cb6f39f5dc389bf41b7a2073f8/packages/@mantine/core/src/core/MantineProvider/merge-mantine-theme/merge-mantine-theme.ts#L10-L46","documentation":"Mantine validates that primaryShade (when an object with dark/light keys) contains integer shade indices 0-9. This error is thrown at theme validation when either primaryShade.dark or primaryShade.light is not an integer in the valid range (e.g. 4.5, a string, or out-of-range).","triggerScenarios":"createTheme({ primaryShade: { light: 4.5, dark: 8 } }); passing a string like '5'; passing a negative number or a value above 9.","commonSituations":"Reading shade values from CSS variables or config files where they arrive as strings; calculations producing fractional shades; copy-pasted theme snippets with typo'd shade values.","solutions":["Set integer shades between 0 and 9 for both dark and light","Coerce config values: Number(...)/parseInt and validate range before building the theme"],"exampleFix":"// before\nconst theme = createTheme({ primaryShade: { light: 4.5, dark: 8 } });\n\n// after\nconst theme = createTheme({ primaryShade: { light: 4, dark: 8 } });","handlingStrategy":"validation","validationCode":"const shade = (v: unknown) =>\n  Number.isInteger(v) && v >= 0 && v <= 9 ? v : 5;\n\ncreateTheme({\n  primaryShade: { light: shade(cfg.light), dark: shade(cfg.dark) },\n});","typeGuard":"function isValidShade(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 9;\n}","tryCatchPattern":null,"preventionTips":["Parse shade values from config with Number() and round","Keep shades as literal integers in theme files","Validate theme objects with a unit test"],"tags":["theme","primary-shade","configuration"],"backgroundTag":"theme-validation-failed","analyzedSha":"8a284e2c2c53a9cb6f39f5dc389bf41b7a2073f8","analyzedAt":"2026-08-28T10:25:51.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}