{"record":{"id":"cb0a110482ccdec4","repo":"mrdoob/three.js","slug":"three-indexnode-unknown-scope-scope","errorCode":null,"errorMessage":"THREE.IndexNode: Unknown scope: ${scope}","messagePattern":"THREE\\.IndexNode: Unknown scope: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/nodes/core/IndexNode.js","lineNumber":86,"sourceCode":"\t\t} else if ( scope === IndexNode.DRAW ) {\n\n\t\t\tpropertyName = builder.getDrawIndex();\n\n\t\t} else if ( scope === IndexNode.INVOCATION_LOCAL ) {\n\n\t\t\tpropertyName = builder.getInvocationLocalIndex();\n\n\t\t} else if ( scope === IndexNode.INVOCATION_SUBGROUP ) {\n\n\t\t\tpropertyName = builder.getInvocationSubgroupIndex();\n\n\t\t} else if ( scope === IndexNode.SUBGROUP ) {\n\n\t\t\tpropertyName = builder.getSubgroupIndex();\n\n\t\t} else {\n\n\t\t\tthrow new Error( 'THREE.IndexNode: Unknown scope: ' + scope );\n\n\t\t}\n\n\t\tlet output;\n\n\t\tif ( builder.shaderStage === 'vertex' || builder.shaderStage === 'compute' ) {\n\n\t\t\toutput = propertyName;\n\n\t\t} else {\n\n\t\t\tconst nodeVarying = varying( this );\n\n\t\t\toutput = nodeVarying.build( builder, nodeType );\n\n\t\t}\n\n\t\treturn output;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/nodes/core/IndexNode.js#L68-L104","documentation":"Thrown by IndexNode.generate() when the node's `scope` does not match any of the defined IndexNode static scopes. Valid scopes are 'vertex', 'instance', 'draw', 'invocationLocal', 'invocationSubgroup', 'subgroup'. The constructor accepts any string, so the error is deferred to build/generate time rather than construction.","triggerScenarios":"Constructing `new IndexNode('foo')` or `new IndexNode('invocationGlobal')` (a removed/renamed scope), or passing a typo like 'Vertex' (capitalized) or 'instanceIndex'. Also triggered by directly mutating `.scope` on an existing IndexNode to an invalid value.","commonSituations":"Using a stale scope name from an older Three.js version (e.g. the deprecated 'invocationGlobal' was renamed); passing a camelCase/wrong-case string; copy-pasting a scope literal from outdated docs; building a custom node that wraps IndexNode with a configurable scope.","solutions":["Use one of the exported immutable TSL objects (vertexIndex, instanceIndex, drawIndex, invocationLocalIndex, invocationSubgroupIndex, subgroupIndex) instead of constructing IndexNode manually.","If you must construct it, pass an IndexNode static constant, e.g. `new IndexNode(IndexNode.VERTEX)`.","Check the scope spelling and case against the constants defined in src/nodes/core/IndexNode.js:110-115."],"exampleFix":"// before\nconst idx = new IndexNode( 'invocationGlobal' );\n\n// after\nimport { invocationLocalIndex } from 'three/tsl';\nconst idx = invocationLocalIndex;","handlingStrategy":"validation","validationCode":"import { IndexNode } from 'three/nodes';\n\nconst VALID_SCOPES = new Set( [ 'vertex', 'instance', 'draw', 'invocationLocal', 'invocationSubgroup', 'subgroup' ] );\nfunction assertScope( scope ) {\n  if ( ! VALID_SCOPES.has( scope ) ) throw new TypeError( `Invalid IndexNode scope: ${ scope }` );\n}","typeGuard":"const VALID_SCOPES = new Set( [ IndexNode.VERTEX, IndexNode.INSTANCE, IndexNode.DRAW, IndexNode.INVOCATION_LOCAL, IndexNode.INVOCATION_SUBGROUP, IndexNode.SUBGROUP ] );\nconst isValidScope = ( s ) => VALID_SCOPES.has( s );","tryCatchPattern":null,"preventionTips":["Prefer the exported TSL singletons (vertexIndex, instanceIndex, etc.) over manual construction.","If constructing, pass IndexNode static constants, never string literals.","Check scope names against the current Three.js version after upgrades."],"tags":["tsl","index-node","shader-stage","argument-validation"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}