BabylonJS/Babylon.js · error

Error parsing node connections

Error message

Error parsing node connections

What it means

Thrown in _parseNodeConnections (called from serializeToFlowGraph) when the internal parsed-node list and the glTF nodes array are out of sync, or a glTF node's declaration has no mapping. The first branch is a defensive check that should never happen (parsed node without a backing glTF node); the second mirrors error 706 at connection-wiring time.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.ts:324

                    if (value !== undefined) {
                        // Update the flow graph block config.
                        block.config[propertyMapping?.name || key] = {
                            value: value,
                        };
                    }
                }
            }
        }
    }

    private _parseNodeConnections(context: ISerializedFlowGraphContext) {
        for (let i = 0; i < this._nodes.length; i++) {
            // get the corresponding gltf node
            const gltfNode = this._interactivityGraph.nodes?.[i];
            if (!gltfNode) {
                // should never happen but let's still check
                Logger.Error(["No node found for interactivity node", this._nodes[i]]);
                throw new Error("Error parsing node connections");
            }
            const flowGraphBlocks = this._nodes[i];
            const outputMapper = this._mappings[gltfNode.declaration];
            // validate
            if (!outputMapper) {
                Logger.Error(["No mapping found for node", gltfNode]);
                throw new Error("Error parsing node connections");
            }
            // KHR_interactivity spec section 3.2.4 "Unsupported Operations":
            // nodes referring to unsupported operations are demoted to no-ops.
            // Activations of their input flow sockets are ignored, their output
            // flow sockets are never activated, and their output value sockets
            // return constant type-default values. They have no backing
            // FlowGraph blocks (blocks.length === 0), so there is nothing to
            // wire for this node — skip all of its connections.
            if (flowGraphBlocks.blocks.length === 0) {
                Logger.Warn(`Skipping connections for no-op node #${i} (unsupported operation: ${flowGraphBlocks.fullOperationName})`);
                continue;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Do not mutate the interactivity graph object after constructing the parser and before calling serializeToFlowGraph
  2. Ensure every node's `declaration` index is within [0, declarations.length) so mappings resolve
  3. Re-create the parser instance from the final graph data instead of reusing a stale one
  4. Validate the glTF interactivity extension before loading

Example fix

// before: graph edited between parse and serialize
const parser = new InteractivityGraphToFlowGraphParser(graph, gltf);
graph.nodes.splice(0, 1); // desync
parser.serializeToFlowGraph(context);
// after
const parser = new InteractivityGraphToFlowGraphParser(graph, gltf);
parser.serializeToFlowGraph(context);
Defensive patterns

Strategy: try-catch

Validate before calling

// Immediately before serializeToFlowGraph:
const nodes = graph.nodes ?? [];
for (let i = 0; i < nodes.length; i++) {
  if (!nodes[i] || !(parser.arrays.mappings[nodes[i].declaration])) {
    throw new Error(`Node ${i} missing or unmapped before serialization`);
  }
}

Type guard

function graphIntactForSerialization(graph: IKHRInteractivity_Graph, parser: InteractivityGraphToFlowGraphParser): boolean {
  return (graph.nodes?.length ?? 0) === parser.arrays.nodes.length &&
    (graph.nodes ?? []).every((n) => parser.arrays.mappings[n.declaration] != null);
}

Try / catch

try {
  const serialized = parser.serializeToFlowGraph(context);
} catch (e) {
  if (e.message === 'Error parsing node connections') {
    console.warn('Graph changed after parsing; rebuilding parser');
    const fresh = new InteractivityGraphToFlowGraphParser(graph, gltf);
    return fresh.serializeToFlowGraph(context);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling serializeToFlowGraph after constructing the parser when `interactivityGraph.nodes[i]` is missing for a parsed node i, or when `this._mappings[gltfNode.declaration]` is undefined because the declaration index is out of range of the parsed mappings.

Common situations: Graph mutated after parser construction (nodes removed from the glTF object); assets with out-of-range declaration indices; reusing a parser instance with a modified graph.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/0f4991285f0ded5e. Report an issue: GitHub.