mrdoob/three.js · error · NodeError
THREE.TSL: `texture( value )` function expects a valid insta
Error message
THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().
What it means
Thrown by TextureNode.setup() when the `value` passed to the TSL `texture()` accessor is not a real THREE.Texture. The guard is `!texture || texture.isTexture !== true`, so the value must be truthy and carry the `isTexture` flag. Note `texture()` defaults its first argument to `EmptyTexture`, so this only fires when the caller explicitly passes `null`/`undefined` or a non-texture object (a Node, a Material, a number, a render target, etc.).
Source
Thrown at src/nodes/accessors/TextureNode.js:362
}
/**
* Setups texture node by preparing the internal nodes for code generation.
*
* @param {NodeBuilder} builder - The current node builder.
*/
setup( builder ) {
const properties = builder.getNodeProperties( this );
properties.referenceNode = this.referenceNode;
//
const texture = this.value;
if ( ! texture || texture.isTexture !== true ) {
throw new NodeError( 'THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().', this.stackTrace );
}
//
const uvNode = Fn( () => {
let uvNode = this.uvNode;
if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {
uvNode = builder.context.getUV( this, builder );
}
if ( ! uvNode ) uvNode = this.getDefaultUV();
if ( this.updateMatrix === true ) {View on GitHub (pinned to da05705fa3)
Solutions
- Ensure the first argument to `texture()` is a THREE.Texture instance (or a TextureNode).
- If referencing a render target, pass `renderTarget.texture`, not the render target object.
- If the texture is loaded asynchronously, defer node construction until the texture exists, or rely on the default `EmptyTexture` by omitting the argument.
- Switch to `cubeTexture()` for cube maps and `texture3D()` for 3D textures.
Example fix
// before material.colorNode = texture( myRenderTarget ); // after material.colorNode = texture( myRenderTarget.texture );
Defensive patterns
Strategy: type-guard
Validate before calling
import { Texture } from 'three';
function resolveTextureValue( value ) {
if ( value && value.isTextureNode === true ) return value; // texture node ok
if ( value && value.isTexture === true ) return value;
return null; // caller should fall back to a default texture or skip
}
// before building the material graph:
const tex = resolveTextureValue( maybeTexture );
if ( tex === null ) throw new Error( 'texture() requires a THREE.Texture' ); Type guard
const isTextureLike = ( v ) => !! v && ( v.isTexture === true || v.isTextureNode === true ); // usage material.colorNode = isTextureLike( myTex ) ? texture( myTex ) : texture();
Try / catch
try {
material.colorNode = texture( value );
renderer.compileAsync( scene, camera ); // build happens here
} catch ( e ) {
if ( /expects a valid instance of THREE\.Texture/.test( e.message ) ) {
material.colorNode = texture( fallbackTexture );
} else throw e;
} Prevention
- Always pass renderTarget.texture, never the render target object.
- Default the texture argument by omitting it rather than passing null.
- Use cubeTexture()/texture3D() for non-2D textures.
- Type-check async-loaded textures before referencing them in a node graph.
When it happens
Trigger: Calling `texture(null)`, `texture(undefined)`, `texture(someMaterial)`, `texture(someNode)`, or passing a `WebGLRenderTarget` instead of `renderTarget.texture`. Also fires if a texture variable is asynchronously loaded but referenced before assignment completes and the caller passed a placeholder non-texture.
Common situations: Forgetting `.texture` on a RenderTarget/RT (passing the RT object itself); passing a `CubeTexture` to `texture()` instead of `cubeTexture()`; referencing a texture field of a material/uniform that resolves to null at build time; passing a `DataTexture` that failed to construct; mixing up the `textureLoad`/`texture` argument order.
Related errors
- THREE.IndexNode: Unknown scope: ${scope}
- Unable to determine texture byte length for ${format} format
- THREE.TextureUtils: Unknown texture type ${type}.
- THREE.TSL: No "ConstNode" found in node graph.
- THREE.FunctionNode: Function is not a GLSL code.
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/37fc7e6a44e8f005.
Report an issue: GitHub.