mrdoob/three.js · error · Error

THREE.Renderer: .initTexture() called before the backend is

Error message

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

What it means

Thrown by Renderer.initTexture() when the backend is not yet initialized. Texture preloading needs the GPU upload machinery (the _textures backend system) which is only available after renderer.init() resolves. The async init must complete before any manual texture upload.

Source

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

		await this.init();

		this.initTexture( texture );

	}

	/**
	 * Initializes the given texture. Useful for preloading a texture rather than waiting until first render
	 * (which can cause noticeable lags due to decode and GPU upload overhead).
	 *
	 * This method can only be used if the renderer has been initialized.
	 *
	 * @param {Texture} texture - The texture.
	 */
	initTexture( texture ) {

		if ( this._initialized === false ) {

			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.' );

View on GitHub (pinned to da05705fa3)

Solutions

  1. Call `await renderer.init();` before `renderer.initTexture(texture);`.
  2. Switch to the deprecated `await renderer.initTextureAsync(texture)` which inits internally (emits deprecation warning).
  3. Defer preloading until after the first render frame, which implicitly initializes the backend.
  4. Group all preload calls behind an `async function prepareAssets()` that awaits init first.

Example fix

// before
const renderer = new WebGPURenderer();
renderer.initTexture(envMap); // throws

// after
const renderer = new WebGPURenderer();
await renderer.init();
renderer.initTexture(envMap);
Defensive patterns

Strategy: validation

Validate before calling

async function preloadTexture(renderer, texture) {
  if (!renderer.hasInitialized()) await renderer.init();
  renderer.initTexture(texture);
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling renderer.initTexture(texture) right after `new WebGPURenderer()` (or any common Renderer subclass) without awaiting init, typically to preload a texture before the first render to avoid a startup hitch.

Common situations: App startup routines that preload env maps, fonts, or sprite atlases synchronously. Migrating from `initTextureAsync` (deprecated) without adding the explicit `await renderer.init()`. SSR/server code paths where init was never triggered.

Related errors


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