emotion-js/emotion · error · Error

Could not get unrendered element reliably from the Enzyme's

Error message

Could not get unrendered element reliably from the Enzyme's ShallowWrapper. This is a bug in Emotion - please open an issue with repro steps included:
https://github.com/emotion-js/emotion/issues/new?assignees=&labels=bug%2C+needs+triage&template=--bug-report.md&title=

What it means

create-enzyme-serializer's getUnrenderedElement inspects Enzyme ShallowWrapper's internal symbol properties to find exactly one React element. If zero or multiple element-valued symbols are found, the internals could not be interpreted reliably, so it throws and asks for a bug report. This usually means the Enzyme version's internals no longer match what emotion's serializer expects.

Source

Thrown at packages/jest/src/create-enzyme-serializer.js:36

      return {
        ...json,
        children: json.children.slice(-1)
      }
    }
    return json
  }
})

// this is a hack, leveraging the internal/implementation knowledge about the enzyme's ShallowWrapper
// there is no sane way to get this information otherwise though
const getUnrenderedElement = shallowWrapper => {
  const symbols = Object.getOwnPropertySymbols(shallowWrapper)
  const elementValues = symbols.filter(sym => {
    const val = shallowWrapper[sym]
    return !!val && val.$$typeof === Symbol.for('react.element')
  })
  if (elementValues.length !== 1) {
    throw new Error(
      "Could not get unrendered element reliably from the Enzyme's ShallowWrapper. This is a bug in Emotion - please open an issue with repro steps included:\n" +
        'https://github.com/emotion-js/emotion/issues/new?assignees=&labels=bug%2C+needs+triage&template=--bug-report.md&title='
    )
  }
  return shallowWrapper[elementValues[0]]
}

const wrappedEnzymeSerializer = {
  test: enzymeToJsonSerializer.test,
  print: (enzymeWrapper, printer) => {
    const isShallow = !!enzymeWrapper.dive

    if (isShallow && enzymeWrapper.root() === enzymeWrapper) {
      const unrendered = getUnrenderedElement(enzymeWrapper)
      if (
        isEmotionCssPropElementType(unrendered) ||
        isStyledElementType(unrendered)
      ) {

View on GitHub (pinned to b882bcba85)

Solutions

  1. Pin compatible versions of enzyme, enzyme-adapter-react-* and @emotion/jest / jest-emotion
  2. Pass the rendered root element (or use mount) instead of the ShallowWrapper when testing styles
  3. Render only a single root element from the component under test
  4. Open an emotion issue with repro steps as the message requests if versions are current

Example fix

// before
const wrapper = shallow(<MyButton />)
expect(wrapper).toHaveStyleRule('color', 'red')

// after
const wrapper = mount(<MyButton />)
expect(wrapper.find('button')).toHaveStyleRule('color', 'red')
Defensive patterns

Strategy: validation

Validate before calling

function hasSingleReactElement(wrapper) {
  const syms = Object.getOwnPropertySymbols(wrapper)
  const count = syms.filter(s => {
    const v = wrapper[s]
    return !!v && v.$$typeof === Symbol.for('react.element')
  }).length
  return count === 1
}

Type guard

function isReactElement(v) {
  return !!v && v.$$typeof === Symbol.for('react.element')
}

Prevention

When it happens

Trigger: Calling toHaveStyleRule / toMatchEmotionSnapshot on an Enzyme shallow() wrapper when Object.getOwnPropertySymbols(wrapper) yields a count of React-element-typed values other than exactly 1 — typically with incompatible Enzyme or React versions.

Common situations: Upgrading React or Enzyme so ShallowWrapper internals changed; shallow-rendering a component that renders fragments/multiple roots; using a wrapper type emotion's serializer doesn't support.

Related errors


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