emotion-js/emotion · error · Error

Emotion key must only contain lower case alphabetical charac

Error message

Emotion key must only contain lower case alphabetical characters and - but "${key}" was passed

What it means

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.

Source

Thrown at packages/cache/src/index.ts:93

      // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector
      // Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)
      // so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles
      // will not result in the Emotion 10 styles being destroyed
      const dataEmotionAttribute = node.getAttribute('data-emotion')!
      if (dataEmotionAttribute.indexOf(' ') === -1) {
        return
      }

      document.head.appendChild(node)
      node.setAttribute('data-s', '')
    })
  }

  const stylisPlugins = options.stylisPlugins || defaultStylisPlugins

  if (isDevelopment) {
    if (/[^a-z-]/.test(key)) {
      throw new Error(
        `Emotion key must only contain lower case alphabetical characters and - but "${key}" was passed`
      )
    }
  }
  let inserted: EmotionCache['inserted'] = {}
  let container: Node
  const nodesToHydrate: HTMLStyleElement[] = []
  if (isBrowser) {
    container = options.container || document.head

    Array.prototype.forEach.call(
      // this means we will ignore elements which don't have a space in them which
      // means that the style elements we're looking at are only Emotion 11 server-rendered style elements
      document.querySelectorAll(`style[data-emotion^="${key} "]`),
      (node: HTMLStyleElement) => {
        const attrib = node.getAttribute(`data-emotion`)!.split(' ')
        for (let i = 1; i < attrib.length; i++) {
          inserted[attrib[i]] = true

View on GitHub (pinned to b882bcba85)

Solutions

  1. Lowercase the key and remove invalid characters: 'MyApp' -> 'my-app'
  2. Replace underscores/digits with hyphens or letters
  3. Sanitize the key programmatically before passing to createCache

Example fix

// before
const cache = createCache({ key: 'MyApp_1' })
// after
const cache = createCache({ key: 'my-app' })
Defensive patterns

Strategy: validation

Validate before calling

const key = 'MyApp';
if (/[^a-z-]/.test(key)) throw new Error(`Invalid cache key: ${key}`);

Type guard

const isValidEmotionKey = (k) => typeof k === 'string' && !/[^a-z-]/.test(k);

Prevention

When it happens

Trigger: Calling createCache({ key: 'MyApp' }) or key: 'app_1' — any key with characters outside a-z and '-'.

Common situations: Using PascalCase brand names, keys with underscores or numbers, or deriving the key from an npm package name containing @ or /.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of emotion-js/emotion@b882bcba85 (2026-09-02). Data as JSON: /api/errors/b568b5e7ab2339c5. Report an issue: GitHub.