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
- Remove the onUncaughtError option from the render() call.
- Assert errors from your component with expect(() => render(...)).toThrow(...) or an error boundary instead of an onUncaughtError callback.
- If you need custom uncaught-error logging, wrap the component under test in an error boundary component.
- 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
- Never copy createRoot-only options (onUncaughtError) into RTL render() options.
- Test thrown render errors with expect(() => render(...)).toThrow() instead of callbacks.
- Use error boundaries or onCaughtError/onRecoverableError (supported) for error-path coverage.
- When migrating from a manual createRoot harness to RTL, audit the options object you pass along.
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.