mrdoob/three.js · error · Error
THREE.Renderer: .compute() expects a ComputeNode.
Error message
THREE.Renderer: .compute() expects a ComputeNode.
What it means
Thrown by Renderer.compute() when the computeNodes argument is not a ComputeNode. Like compileComputeAsync, compute() accepts a single ComputeNode or an array, but the synchronous compute() path only checks the first element (computeList[0]); if it is undefined or lacks isComputeNode === true, the call is rejected.
Source
Thrown at src/renderers/common/Renderer.js:2927
//
this.backend.updateTimeStampUID( computeNodes );
this.inspector.beginCompute( this.backend.getTimestampUID( computeNodes ), computeNodes );
//
const backend = this.backend;
const pipelines = this._pipelines;
const bindings = this._bindings;
const nodes = this._nodes;
const computeList = Array.isArray( computeNodes ) ? computeNodes : [ computeNodes ];
if ( computeList[ 0 ] === undefined || computeList[ 0 ].isComputeNode !== true ) {
throw new Error( 'THREE.Renderer: .compute() expects a ComputeNode.' );
}
backend.beginCompute( computeNodes );
for ( const computeNode of computeList ) {
// onInit
if ( pipelines.has( computeNode ) === false ) {
const dispose = () => {
computeNode.removeEventListener( 'dispose', dispose );
pipelines.delete( computeNode );
bindings.deleteForCompute( computeNode );
nodes.delete( computeNode );View on GitHub (pinned to da05705fa3)
Solutions
- Build a proper ComputeNode (e.g. via TSL Fn(...).compute(count) or new THREE.ComputeNode) and pass that.
- Guard: if (node && node.isComputeNode) renderer.compute(node);
- When passing an array, ensure the first element is a valid ComputeNode (filter first).
- Check that async node construction completed before calling compute.
Example fix
// before
renderer.compute( computeKernel ); // not a ComputeNode
// after
const computeNode = Fn( () => { /* ... */ } ).compute( count );
renderer.compute( computeNode ); Defensive patterns
Strategy: type-guard
Validate before calling
const list = ( Array.isArray( computeNodes ) ? computeNodes : [ computeNodes ] ) .filter( n => n && n.isComputeNode === true ); if ( list.length && isComputeNode( list[ 0 ] ) ) renderer.compute( list );
Type guard
function isComputeNode( node ) {
return node != null && node.isComputeNode === true;
} Prevention
- Build ComputeNodes via TSL Fn(...).compute(count) or new THREE.ComputeNode.
- Guard compute() with node && node.isComputeNode.
- Ensure the first array element is a valid ComputeNode (filter first).
- Confirm async node construction finished before calling compute.
When it happens
Trigger: Passing undefined, null, a material, a plain object, or an empty/non-ComputeNode first element to renderer.compute(). Submitting compute work before the node was constructed.
Common situations: Calling compute() with a variable that was conditionally assigned and is undefined; passing a compute pipeline/binding object instead of the ComputeNode; TSL/WGSL migration where the node constructor differs.
Related errors
- THREE.Renderer: .compileComputeAsync() expects a ComputeNode
- THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinat
- THREE.Renderer: .render() called before the backend is initi
- THREE.Renderer: "getArrayBufferAsync()" offset and count mus
- THREE.Renderer: .hasFeature() called before the backend is i
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/1c2cd617b8b65815.
Report an issue: GitHub.