{"record":{"id":"ad50e06a15ec1333","repo":"GraphiteEditor/Graphite","slug":"failed-to-create-combine-paths-node","errorCode":null,"errorMessage":"Failed to create combine paths node","messagePattern":"Failed to create combine paths node","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/tool/common_functionality/graph_modification_utils.rs","lineNumber":106,"sourceCode":"\t\tis_layer: false,\n\t});\n\tresponses.add(NodeGraphMessage::MoveNodeToChainStart {\n\t\tnode_id: merge_node_id,\n\t\tparent: first_layer,\n\t});\n\tresponses.add(NodeGraphMessage::ConnectUpstreamOutputToInput {\n\t\tdownstream_input: InputConnector::layer_secondary_input(second_layer.to_node()),\n\t\tinput_connector: InputConnector::layer_secondary_input(merge_node_id),\n\t});\n\tresponses.add(NodeGraphMessage::DeleteNodes {\n\t\tnode_ids: vec![second_layer.to_node()],\n\t\tdelete_children: false,\n\t});\n\n\t// Add a Combine Paths node after the merge\n\tlet combine_paths_node_id = NodeId::new();\n\tlet combine_paths_node = document_node_definitions::resolve_proto_node_type(graphene_std::vector::combine_paths::IDENTIFIER)\n\t\t.expect(\"Failed to create combine paths node\")\n\t\t.default_node_template();\n\tresponses.add(NodeGraphMessage::InsertNode {\n\t\tnode_id: combine_paths_node_id,\n\t\tnode_template: Box::new(combine_paths_node),\n\t});\n\tresponses.add(NodeGraphMessage::MoveNodeToChainStart {\n\t\tnode_id: combine_paths_node_id,\n\t\tparent: first_layer,\n\t});\n\n\t// Add a path node after the combine paths node\n\tlet path_node_id = NodeId::new();\n\tlet path_node = document_node_definitions::resolve_network_node_type(\"Path\")\n\t\t.expect(\"Failed to create path node\")\n\t\t.default_node_template();\n\tresponses.add(NodeGraphMessage::InsertNode {\n\t\tnode_id: path_node_id,\n\t\tnode_template: Box::new(path_node),","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/tool/common_functionality/graph_modification_utils.rs#L88-L124","documentation":"The same merge flow then inserts a Combine Paths node by resolving graphene_std::vector::combine_paths::IDENTIFIER through resolve_proto_node_type(...).expect(\"Failed to create combine paths node\"). This is a DOCUMENT_NODE_TYPES lookup keyed by ProtoNodeIdentifier; None means the proto node identifier is not registered in this build. Because the identifier comes from the defining crate it is normally stable, so a panic here indicates the registry population and the vector module drifted (renamed identifier, feature-gated module).","triggerScenarios":"Running the two-layer merge (both layers with vector data) when combine_paths::IDENTIFIER is absent from DOCUMENT_NODE_TYPES - renamed constant, changed crate structure, or a build with the vector module compiled out.","commonSituations":"Refactors of graphene_std node identifiers; feature flags excluding vector nodes from the registry; version skew between editor and graphene_std crates.","solutions":["Verify combine_paths::IDENTIFIER matches the registered identifier in document_node_definitions after any rename","Downgrade the expect to a logged early-return that cancels the merge cleanly","Add a registry-coverage test for all identifiers referenced from tooling code paths"],"exampleFix":"// before\nlet combine_paths_node = document_node_definitions::resolve_proto_node_type(graphene_std::vector::combine_paths::IDENTIFIER)\n\t.expect(\"Failed to create combine paths node\")\n\t.default_node_template();\n\n// after\nlet Some(def) = document_node_definitions::resolve_proto_node_type(graphene_std::vector::combine_paths::IDENTIFIER) else {\n\tlog::error!(\"Combine Paths node definition missing from registry\");\n\treturn;\n};\nlet combine_paths_node = def.default_node_template();","handlingStrategy":"validation","validationCode":"let Some(combine_def) = document_node_definitions::resolve_proto_node_type(graphene_std::vector::combine_paths::IDENTIFIER) else {\n\tlog::error!(\"Combine Paths node missing from registry\");\n\treturn;\n};","typeGuard":"fn proto_node_registered(identifier: graphene_std::ProtoNodeIdentifier) -> bool {\n\tdocument_node_definitions::resolve_proto_node_type(identifier).is_some()\n}","tryCatchPattern":null,"preventionTips":["Reference identifiers via their crate constants (IDENTIFIER) instead of retyped strings so renames propagate","Check all node resolutions for a flow up front, then apply the queued messages atomically","Unit-test the merge flow end-to-end so a registry drift fails in CI"],"tags":["rust","node-registry","combine-paths","lookup-miss","panic"],"backgroundTag":"node-definition-not-found","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}