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
- Call `await renderer.init();` before `renderer.initTexture(texture);`.
- Switch to the deprecated `await renderer.initTextureAsync(texture)` which inits internally (emits deprecation warning).
- Defer preloading until after the first render frame, which implicitly initializes the backend.
- 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
- Wrap all asset-preload routines in an async function whose first line is `await renderer.init();`.
- Avoid calling initTexture from synchronous constructors or module top-level code.
- Track readiness with renderer.hasInitialized() in your asset manager.
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
- THREE.Renderer: .hasFeature() called before the backend is i
- THREE.Renderer: .initRenderTarget() called before the backen
- THREE.Renderer: .hasCompatibility() called before the backen
- THREE.Renderer: .render() called before the backend is initi
- THREE.PMREMGenerator: .fromScene() called before the backend
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/6edc7aedef25d52d.
Report an issue: GitHub.