{"record":{"id":"37fc7e6a44e8f005","repo":"mrdoob/three.js","slug":"three-tsl-texture-value-function-expects-a-v","errorCode":null,"errorMessage":"THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().","messagePattern":"THREE\\.TSL: `texture\\( value \\)` function expects a valid instance of THREE\\.Texture\\(\\)\\.","errorType":"exception","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"src/nodes/accessors/TextureNode.js","lineNumber":362,"sourceCode":"\t}\n\n\t/**\n\t * Setups texture node by preparing the internal nodes for code generation.\n\t *\n\t * @param {NodeBuilder} builder - The current node builder.\n\t */\n\tsetup( builder ) {\n\n\t\tconst properties = builder.getNodeProperties( this );\n\t\tproperties.referenceNode = this.referenceNode;\n\n\t\t//\n\n\t\tconst texture = this.value;\n\n\t\tif ( ! texture || texture.isTexture !== true ) {\n\n\t\t\tthrow new NodeError( 'THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().', this.stackTrace );\n\n\t\t}\n\n\t\t//\n\n\t\tconst uvNode = Fn( () => {\n\n\t\t\tlet uvNode = this.uvNode;\n\n\t\t\tif ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {\n\n\t\t\t\tuvNode = builder.context.getUV( this, builder );\n\n\t\t\t}\n\n\t\t\tif ( ! uvNode ) uvNode = this.getDefaultUV();\n\n\t\t\tif ( this.updateMatrix === true ) {","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/nodes/accessors/TextureNode.js#L344-L380","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nmaterial.colorNode = texture( myRenderTarget );\n\n// after\nmaterial.colorNode = texture( myRenderTarget.texture );","handlingStrategy":"type-guard","validationCode":"import { Texture } from 'three';\n\nfunction resolveTextureValue( value ) {\n  if ( value && value.isTextureNode === true ) return value; // texture node ok\n  if ( value && value.isTexture === true ) return value;\n  return null; // caller should fall back to a default texture or skip\n}\n\n// before building the material graph:\nconst tex = resolveTextureValue( maybeTexture );\nif ( tex === null ) throw new Error( 'texture() requires a THREE.Texture' );","typeGuard":"const isTextureLike = ( v ) => !! v && ( v.isTexture === true || v.isTextureNode === true );\n\n// usage\nmaterial.colorNode = isTextureLike( myTex ) ? texture( myTex ) : texture();","tryCatchPattern":"try {\n  material.colorNode = texture( value );\n  renderer.compileAsync( scene, camera ); // build happens here\n} catch ( e ) {\n  if ( /expects a valid instance of THREE\\.Texture/.test( e.message ) ) {\n    material.colorNode = texture( fallbackTexture );\n  } else throw e;\n}","preventionTips":["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."],"tags":["tsl","texture","node-material","argument-validation"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}