mrdoob/three.js · error · Error

THREE.Renderer: .initRenderTarget() called before the backen

Error message

THREE.Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before using this method.

What it means

Thrown by Renderer.initRenderTarget() when the backend is not yet initialized. Preloading a render target (allocating its GPU textures and render context) requires the texture subsystem to exist, which only happens after renderer.init() resolves.

Source

Thrown at src/renderers/common/Renderer.js:3108

			throw new Error( 'THREE.Renderer: .initTexture() called before the backend is initialized. Use "await renderer.init();" before using this method.' );

		}

		this._textures.updateTexture( texture );

	}

	/**
	 * Initializes the given render target.
	 *
	 * @param {RenderTarget} renderTarget - The render target to intialize.
	 */
	initRenderTarget( renderTarget ) {

		if ( this._initialized === false ) {

			throw new Error( 'THREE.Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before using this method.' );

		}

		this._textures.updateRenderTarget( renderTarget );

		const renderTargetData = this._textures.get( renderTarget );

		const renderContext = this._renderContexts.get( renderTarget );

		renderContext.textures = renderTargetData.textures;
		renderContext.depthTexture = renderTargetData.depthTexture;
		renderContext.width = renderTargetData.width;
		renderContext.height = renderTargetData.height;
		renderContext.renderTarget = renderTarget;
		renderContext.depth = renderTarget.depthBuffer;
		renderContext.stencil = renderTarget.stencilBuffer;

		this.backend.initRenderTarget( renderContext );

View on GitHub (pinned to da05705fa3)

Solutions

  1. Call `await renderer.init();` before `renderer.initRenderTarget(rt);`.
  2. Defer render-target initialization until the first render pass, which initializes the backend as a side effect.
  3. Move render-target construction into an async setup phase that runs after init resolves.

Example fix

// before
const renderer = new WebGPURenderer();
renderer.initRenderTarget(shadowTarget); // throws

// after
const renderer = new WebGPURenderer();
await renderer.init();
renderer.initRenderTarget(shadowTarget);
Defensive patterns

Strategy: validation

Validate before calling

async function preloadRenderTarget(renderer, rt) {
  if (!renderer.hasInitialized()) await renderer.init();
  renderer.initRenderTarget(rt);
}

Type guard

function rendererReady(renderer) {
  return typeof renderer.hasInitialized === 'function' && renderer.hasInitialized();
}

Try / catch

try {
  renderer.initRenderTarget(rt);
} catch (e) {
  if (/initRenderTarget\(\) called before/.test(e.message)) { await renderer.init(); renderer.initRenderTarget(rt); }
  else throw e;
}

Prevention

When it happens

Trigger: Calling renderer.initRenderTarget(renderTarget) on a newly built WebGPURenderer/Renderer without first awaiting renderer.init(), usually to warm up a render target (shadow map, G-buffer, post-processing buffer) before the first frame.

Common situations: Post-processing setups that preallocate render targets at app start. Shadow map configurations created before the first render. Code migrated from older versions where the constructor did synchronous init.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/59821fe9c21e76cd. Report an issue: GitHub.