{"record":{"id":"b568b5e7ab2339c5","repo":"emotion-js/emotion","slug":"emotion-key-must-only-contain-lower-case-alphabeti","errorCode":null,"errorMessage":"Emotion key must only contain lower case alphabetical characters and - but \"${key}\" was passed","messagePattern":"Emotion key must only contain lower case alphabetical characters and - but \"(.+?)\" was passed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cache/src/index.ts","lineNumber":93,"sourceCode":"      // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector\n      // Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)\n      // so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles\n      // will not result in the Emotion 10 styles being destroyed\n      const dataEmotionAttribute = node.getAttribute('data-emotion')!\n      if (dataEmotionAttribute.indexOf(' ') === -1) {\n        return\n      }\n\n      document.head.appendChild(node)\n      node.setAttribute('data-s', '')\n    })\n  }\n\n  const stylisPlugins = options.stylisPlugins || defaultStylisPlugins\n\n  if (isDevelopment) {\n    if (/[^a-z-]/.test(key)) {\n      throw new Error(\n        `Emotion key must only contain lower case alphabetical characters and - but \"${key}\" was passed`\n      )\n    }\n  }\n  let inserted: EmotionCache['inserted'] = {}\n  let container: Node\n  const nodesToHydrate: HTMLStyleElement[] = []\n  if (isBrowser) {\n    container = options.container || document.head\n\n    Array.prototype.forEach.call(\n      // this means we will ignore elements which don't have a space in them which\n      // means that the style elements we're looking at are only Emotion 11 server-rendered style elements\n      document.querySelectorAll(`style[data-emotion^=\"${key} \"]`),\n      (node: HTMLStyleElement) => {\n        const attrib = node.getAttribute(`data-emotion`)!.split(' ')\n        for (let i = 1; i < attrib.length; i++) {\n          inserted[attrib[i]] = true","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/emotion-js/emotion/blob/b882bcba85132554992e4bd49e94c95939bbf810/packages/cache/src/index.ts#L75-L111","documentation":"The emotion cache `key` becomes CSS class prefixes and data attributes, so it must be safe in CSS: only lowercase letters and hyphens. In development, createCache validates the key with /[^a-z-]/ and throws if it contains uppercase letters, digits, or symbols.","triggerScenarios":"Calling createCache({ key: 'MyApp' }) or key: 'app_1' — any key with characters outside a-z and '-'.","commonSituations":"Using PascalCase brand names, keys with underscores or numbers, or deriving the key from an npm package name containing @ or /.","solutions":["Lowercase the key and remove invalid characters: 'MyApp' -> 'my-app'","Replace underscores/digits with hyphens or letters","Sanitize the key programmatically before passing to createCache"],"exampleFix":"// before\nconst cache = createCache({ key: 'MyApp_1' })\n// after\nconst cache = createCache({ key: 'my-app' })","handlingStrategy":"validation","validationCode":"const key = 'MyApp';\nif (/[^a-z-]/.test(key)) throw new Error(`Invalid cache key: ${key}`);","typeGuard":"const isValidEmotionKey = (k) => typeof k === 'string' && !/[^a-z-]/.test(k);","tryCatchPattern":null,"preventionTips":["Use kebab-case keys (e.g. 'my-app') only","Sanitize derived keys: key.replace(/[^a-z-]/g, '').toLowerCase()","Write a test validating cache key format in dev"],"tags":["emotion","cache","validation","configuration"],"backgroundTag":"invalid-enum-value","analyzedSha":"b882bcba85132554992e4bd49e94c95939bbf810","analyzedAt":"2026-09-02T22:27:13.739Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}