mrdoob/three.js · error · Error
THREE.Renderer: .render() called before the backend is initi
Error message
THREE.Renderer: .render() called before the backend is initialized. Use "await renderer.init();" before rendering.
What it means
Thrown by Renderer.render() when the backend has not been initialized. The WebGPU/Nodes Renderer initializes asynchronously; you must await renderer.init() (or any async method that triggers init) before calling render(). Calling render() on an uninitialized renderer has no valid backend to dispatch to.
Source
Thrown at src/renderers/common/Renderer.js:1503
* Renders the scene or 3D object with the given camera. This method can only be called
* if the renderer has been initialized. When using `render()` inside an animation loop,
* it's guaranteed the renderer will be initialized. The animation loop must be defined
* with {@link Renderer#setAnimationLoop} though.
*
* For all other use cases (like when using on-demand rendering), you must call
* {@link Renderer#init} before rendering.
*
* The target of the method is the default framebuffer (meaning the canvas)
* or alternatively a render target when specified via `setRenderTarget()`.
*
* @param {Object3D} scene - The scene or 3D object to render.
* @param {Camera} camera - The camera to render the scene with.
*/
render( scene, camera ) {
if ( this._initialized === false ) {
throw new Error( 'THREE.Renderer: .render() called before the backend is initialized. Use "await renderer.init();" before rendering.' );
}
this._renderScene( scene, camera );
}
/**
* Returns whether the renderer has been initialized or not.
*
* @readonly
* @return {boolean} Whether the renderer has been initialized or not.
*/
get initialized() {
return this._initialized;
}View on GitHub (pinned to da05705fa3)
Solutions
- Call await renderer.init() once after construction, before any render().
- Gate your render loop: do not start requestAnimationFrame until the init promise resolves.
- Use async/await or .then() on init before the first render call.
- If using a framework, perform init in an async setup/effect and render afterwards.
Example fix
// before const renderer = new THREE.WebGPURenderer(); renderer.render( scene, camera ); // throws: not initialized // after const renderer = new THREE.WebGPURenderer(); await renderer.init(); renderer.render( scene, camera );
Defensive patterns
Strategy: validation
Validate before calling
await renderer.init(); renderer.render( scene, camera ); // safe to call now
Prevention
- Always await renderer.init() before the first render.
- Start the requestAnimationFrame loop only after init resolves.
- Treat the async Renderer as async throughout your setup.
- Guard render entry points with an initialized flag.
When it happens
Trigger: Constructing new Renderer/backend and immediately calling renderer.render() in a synchronous code path without awaiting init; calling render before the first async operation completed.
Common situations: Switching from WebGLRenderer (synchronously ready) to the async Renderer/WebGPURenderer and forgetting to await init; framework lifecycle hooks that render before the init promise resolves; top-level module code that renders synchronously.
Related errors
- THREE.Renderer: .resetState() called before the backend is i
- THREE.Renderer: .clear() called before the backend is initia
- THREE.Renderer: .hasFeature() called before the backend is i
- THREE.Renderer: .initTexture() called before the backend is
- THREE.Renderer: .initRenderTarget() called before the backen
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/9c1e4bd230e651f6.
Report an issue: GitHub.