testing-library/react-testing-library · error · Error

onUncaughtError is not supported. The `render` call will alr

Error message

onUncaughtError is not supported. The `render` call will already throw on uncaught errors.

What it means

render() in src/pure.js explicitly rejects the onUncaughtError option (a React 19 createRoot callback). @testing-library/react deliberately does not support it because its render already runs inside act(), where an uncaught error thrown during render propagates and throws from the render() call itself — so a user-supplied onUncaughtError handler could never be honored consistently.

Source

Thrown at src/pure.js:254

}

function render(
  ui,
  {
    container,
    baseElement = container,
    legacyRoot = false,
    onCaughtError,
    onUncaughtError,
    onRecoverableError,
    queries,
    hydrate = false,
    wrapper,
    reactStrictMode,
  } = {},
) {
  if (onUncaughtError !== undefined) {
    throw new Error(
      'onUncaughtError is not supported. The `render` call will already throw on uncaught errors.',
    )
  }
  if (legacyRoot && typeof ReactDOM.render !== 'function') {
    const error = new Error(
      '`legacyRoot: true` is not supported in this version of React. ' +
        'If your app runs React 19 or later, you should remove this flag. ' +
        'If your app runs React 18 or earlier, visit https://react.dev/blog/2022/03/08/react-18-upgrade-guide for upgrade instructions.',
    )
    Error.captureStackTrace(error, render)
    throw error
  }

  if (!baseElement) {
    // default to document.body instead of documentElement to avoid output of potentially-large
    // head elements (such as JSS style blocks) in debug output
    baseElement = document.body
  }

View on GitHub (pinned to 20ce75f290)

Solutions

  1. Remove the onUncaughtError option from the render() call.
  2. Assert errors from your component with expect(() => render(...)).toThrow(...) or an error boundary instead of an onUncaughtError callback.
  3. If you need custom uncaught-error logging, wrap the component under test in an error boundary component.
  4. Keep onCaughtError/onRecoverableError (supported) if you only need those hooks.

Example fix

// before
render(<App />, { onUncaughtError: (error) => log(error) })
// after
expect(() => render(<App />)).toThrow('boom')
Defensive patterns

Strategy: validation

Validate before calling

const options = { onCaughtError: console.error }
if ('onUncaughtError' in options) throw new Error('onUncaughtError is not supported by @testing-library/react render()')
render(<App />, options)

Type guard

function isSupportedRenderOptions(options) {
  return typeof options === 'object' && options !== null && !('onUncaughtError' in options)
}

Try / catch

try {
  render(<App />, options)
} catch (e) {
  if (String(e.message).includes('onUncaughtError is not supported')) {
    const { onUncaughtError, ...rest } = options
    render(<App />, rest)
  } else {
    throw e
  }
}

Prevention

When it happens

Trigger: Calling render(ui, {onUncaughtError: someHandler}) — passing the option at all, even as undefined-valued variable via spread, triggers the throw immediately.

Common situations: Migrating to React 19 where teams copied createRoot options (onUncaughtError, onCaughtError, onRecoverableError) straight into RTL render options; migrating tests from a manual createRoot harness to RTL.

Related errors


AI-assisted analysis of testing-library/react-testing-library@20ce75f290 (2026-09-02). Data as JSON: /api/errors/93ee45d631bef9e3. Report an issue: GitHub.