{"record":{"id":"f86b4017b2fa9efc","repo":"BabylonJS/Babylon.js","slug":"nodeindex-not-found-in-configuration","errorCode":null,"errorMessage":"nodeIndex not found in configuration","messagePattern":"nodeIndex not found in configuration","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/glTF/2.0/Extensions/KHR_node_hoverability.pure.ts","lineNumber":127,"sourceCode":"                isVariable: true,\r\n            },\r\n            {\r\n                input: \"object\",\r\n                output: \"meshUnderPointer\",\r\n                inputBlockIndex: 2,\r\n                outputBlockIndex: 0,\r\n                isVariable: true,\r\n            },\r\n        ],\r\n        extraProcessor(gltfBlock, _declaration, _mapping, _arrays, serializedObjects, context, globalGLTF) {\r\n            // add the glTF to the configuration of the last serialized object\r\n            const serializedObject = serializedObjects[serializedObjects.length - 1];\r\n            serializedObject.config = serializedObject.config || {};\r\n            serializedObject.config.glTF = globalGLTF;\r\n            // find the listener nodeIndex value\r\n            const nodeIndex = gltfBlock.configuration?.[\"nodeIndex\"]?.value?.[0];\r\n            if (nodeIndex === undefined || typeof nodeIndex !== \"number\") {\r\n                throw new Error(\"nodeIndex not found in configuration\");\r\n            }\r\n            const variableName = MeshPointerOverPrefix + nodeIndex;\r\n            // find the nodeIndex value\r\n            serializedObjects[1].config.variable = variableName;\r\n            context._userVariables[variableName] = {\r\n                className: \"Mesh\",\r\n                id: globalGLTF?.nodes?.[nodeIndex]._babylonTransformNode?.id,\r\n                uniqueId: globalGLTF?.nodes?.[nodeIndex]._babylonTransformNode?.uniqueId,\r\n            };\r\n            return serializedObjects;\r\n        },\r\n    });\r\n\r\n    addNewInteractivityFlowGraphMapping(\"event/onHoverOut\", NAME, {\r\n        // using GetVariable as the nodeIndex is a configuration and not a value (i.e. it's not mutable)\r\n        blocks: [FlowGraphBlockNames.PointerOutEvent, FlowGraphBlockNames.GetVariable, FlowGraphBlockNames.IndexOf, \"KHR_interactivity/FlowGraphGLTFDataProvider\"],\r\n        configuration: {\r\n            stopPropagation: { name: \"stopPropagation\" },\r","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_node_hoverability.pure.ts#L109-L145","documentation":"The KHR_node_hoverability extension post-processes the scene with NodeMaterial / serialized blocks. It reads a numeric 'nodeIndex' from the glTF input block's configuration to know which mesh to attach the pointer listener to. If the block configuration lacks a valid numeric nodeIndex, the extension cannot bind the hover variable and throws.","triggerScenarios":"Loading a glTF whose KHR_node_hoverability NodeMaterial serialization omits configuration['nodeIndex'] (missing, wrong type, or empty value array) while processing pointer-over extra blocks via extraProcessor.","commonSituations":"Hand-authored or tool-exported KHR_node_hoverability data where the graph blocks weren't configured with nodeIndex; editing serialized NodeMaterial output by an exporter and dropping configuration keys.","solutions":["Fix the asset so the hover block's configuration includes nodeIndex: { value: [<number>] }.","Re-export the glTF with an exporter that emits KHR_node_hoverability configuration correctly.","Remove the KHR_node_hoverability extension from the asset if hover behavior is not needed."],"exampleFix":"// asset json: before\n\"configuration\": {}\n// after\n\"configuration\": { \"nodeIndex\": { \"value\": [3] } }","handlingStrategy":"validation","validationCode":"const idx = block?.configuration?.nodeIndex?.value?.[0];\nif (typeof idx !== 'number') throw new Error('KHR_node_hoverability block missing numeric nodeIndex');","typeGuard":"function hasNumericNodeIndex(block: any): boolean {\n  const v = block?.configuration?.['nodeIndex']?.value?.[0];\n  return typeof v === 'number' && Number.isFinite(v);\n}","tryCatchPattern":"try { await loader.loadAsync(url); } catch (e) {\n  if (e.message.includes('nodeIndex not found')) {\n    // fall back: load asset without the hoverability extension or fix asset\n  } else throw e;\n}","preventionTips":["Validate KHR_node_hoverability block configuration in CI before shipping assets.","Re-export assets with a conformant exporter after any manual JSON edits.","Prefer removing the extension when hover interactivity is not needed."],"tags":["gltf","extensions","configuration","node-material"],"backgroundTag":"missing-config-key","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}