emotion-js/emotion · error · Error

You have to configure `key` for your cache. Please make sure

Error message

You have to configure `key` for your cache. Please make sure it's unique (and not equal to 'css') as it's used for linking styles to your cache.
If multiple caches share the same key they might "fight" for each other's style elements.

What it means

createCache requires a unique `key` that identifies the cache in the DOM (used as the data attribute/class prefix for linking styles). In development, emotion throws if no key is provided so caches can be traced and won't collide.

Source

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

const defaultStylisPlugins = [prefixer]

let getSourceMap: ((styles: string) => string | undefined) | undefined
if (isDevelopment) {
  let sourceMapPattern =
    /\/\*#\ssourceMappingURL=data:application\/json;\S+\s+\*\//g
  getSourceMap = styles => {
    let matches = styles.match(sourceMapPattern)
    if (!matches) return
    return matches[matches.length - 1]
  }
}

let createCache = (options: Options): EmotionCache => {
  let key = options.key

  if (isDevelopment && !key) {
    throw new Error(
      "You have to configure `key` for your cache. Please make sure it's unique (and not equal to 'css') as it's used for linking styles to your cache.\n" +
        `If multiple caches share the same key they might "fight" for each other's style elements.`
    )
  }

  if (isBrowser && key === 'css') {
    const ssrStyles = document.querySelectorAll(
      `style[data-emotion]:not([data-s])`
    )

    // get SSRed styles out of the way of React's hydration
    // document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be)
    // note this very very intentionally targets all style elements regardless of the key to ensure
    // that creating a cache works inside of render of a React component
    Array.prototype.forEach.call(ssrStyles, (node: HTMLStyleElement) => {
      // we want to only move elements which have a space in the data-emotion attribute value
      // because that indicates that it is an Emotion 11 server-side rendered style elements
      // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector

View on GitHub (pinned to b882bcba85)

Solutions

  1. Add a unique key: createCache({ key: 'my-app' })
  2. Ensure the key is not 'css' (reserved default; triggers a separate warning)
  3. If key genuinely can't be provided, guard cache creation behind the same isDevelopment check you control

Example fix

// before
const cache = createCache({ stylisPlugins: [prefixer] })
// after
const cache = createCache({ key: 'my-app', stylisPlugins: [prefixer] })
Defensive patterns

Strategy: validation

Validate before calling

const key = options.key ?? 'my-app';
if (!key) throw new Error('createCache requires a unique key');
if (key === 'css') throw new Error('key must not be the reserved value "css"');

Type guard

const hasCacheKey = (o) => typeof o === 'object' && o !== null && typeof o.key === 'string' && o.key.length > 0 && o.key !== 'css';

Prevention

When it happens

Trigger: Calling createCache({}) or createCache({ stylisPlugins: [...] }) without options.key while NODE_ENV is development.

Common situations: Setting up emotion's createCache manually in an app or SSR setup and forgetting the key, or spreading options where key got lost.

Understand the failure class

Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.

Related errors


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