{"record":{"id":"d8ad71c1195d7966","repo":"emotion-js/emotion","slug":"speedy-must-be-changed-before-any-rules-are-insert","errorCode":null,"errorMessage":"speedy must be changed before any rules are inserted","messagePattern":"speedy must be changed before any rules are inserted","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/css/src/create-instance.ts","lineNumber":96,"sourceCode":"  const registeredStyles: string[] = []\n  const rawClassName = getRegisteredStyles(\n    registered,\n    registeredStyles,\n    className\n  )\n\n  if (registeredStyles.length < 2) {\n    return className\n  }\n  return rawClassName + css(registeredStyles)\n}\n\nlet createEmotion = (options: Options): Emotion => {\n  let cache = createCache(options)\n\n  ;(cache.sheet as CSSStyleSheet).speedy = function (value: boolean) {\n    if (isDevelopment && this.ctr !== 0) {\n      throw new Error('speedy must be changed before any rules are inserted')\n    }\n    this.isSpeedy = value\n  }\n\n  cache.compat = true\n\n  let css: Emotion['css'] = (\n    ...args: (TemplateStringsArray | Interpolation<unknown>)[]\n  ) => {\n    let serialized = serializeStyles(args, cache.registered, undefined)\n    insertStyles(cache, serialized, false)\n    return `${cache.key}-${serialized.name}`\n  }\n\n  let keyframes: Emotion['keyframes'] = (\n    ...args: (TemplateStringsArray | Interpolation<unknown>)[]\n  ) => {\n    let serialized = serializeStyles(args, cache.registered)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/emotion-js/emotion/blob/b882bcba85132554992e4bd49e94c95939bbf810/packages/css/src/create-instance.ts#L78-L114","documentation":"Emotion's sheet has a speedy mode (uses CSSOM insertInstead of text nodes) for performance. Once any rule has been inserted (sheet.ctr !== 0), toggling speedy changes how earlier rules were rendered, so in development emotion throws to prevent inconsistent styling.","triggerScenarios":"Calling sheet.speedy(true/false) after at least one style rule was inserted into the cache, typically by calling emotion.sheet.speedy after components have rendered.","commonSituations":"Trying to disable speedy for testing after app render, calling speedy inside effects after initial paint, or toggling it from devtools/test setup post-render.","solutions":["Call sheet.speedy(...) before rendering anything / before the first insert","Set the `speedy` option at createCache/createEmotion time instead: createEmotion({ key, speedy: true })","In tests, create a fresh cache per test and configure speedy before inserting"],"exampleFix":"// before\nconst emotion = createEmotion({ key: 'app' })\nrender(<App />)\nemotion.sheet.speedy(true)\n// after\nconst emotion = createEmotion({ key: 'app', speedy: true })\nrender(<App />)","handlingStrategy":"validation","validationCode":"if (cache.sheet.ctr === 0) {\n  cache.sheet.speedy(true);\n} else {\n  console.warn('speedy can only be toggled before any rules are inserted');\n}","typeGuard":"const canToggleSpeedy = (sheet) => sheet.ctr === 0;","tryCatchPattern":"try {\n  emotion.sheet.speedy(true);\n} catch (e) {\n  if (e.message.includes('speedy must be changed')) {\n    console.warn('Too late to toggle speedy; recreate the cache instead');\n  } else {\n    throw e;\n  }\n}","preventionTips":["Set speedy via createCache/createEmotion options, not by patching the sheet after render","Only toggle speedy in bootstrap code that runs before any insert","In tests, build a fresh emotion instance per test before rendering"],"tags":["emotion","css","lifecycle","testing"],"backgroundTag":"lifecycle-order-violation","analyzedSha":"b882bcba85132554992e4bd49e94c95939bbf810","analyzedAt":"2026-09-02T22:27:13.739Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}