{"record":{"id":"9c3d9c3ee8b8dbcd","repo":"GraphiteEditor/Graphite","slug":"path-node-does-not-exist-9c3d9c","errorCode":null,"errorMessage":"Path node does not exist","messagePattern":"Path node does not exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/tool/tool_messages/freehand_tool.rs","lineNumber":301,"sourceCode":"\t\t\t\t\tlet mut selected_layers_except_artboards = selected_nodes.selected_layers_except_artboards(&document.network_interface);\n\t\t\t\t\tlet existing_layer = selected_layers_except_artboards.next().filter(|_| selected_layers_except_artboards.next().is_none());\n\t\t\t\t\tif let Some(layer) = existing_layer {\n\t\t\t\t\t\ttool_data.layer = Some(layer);\n\n\t\t\t\t\t\tlet transform = document.metadata().transform_to_viewport(layer);\n\t\t\t\t\t\tlet position = transform.inverse().transform_point2(input.mouse.position);\n\n\t\t\t\t\t\textend_path_with_next_segment(tool_data, position, false, responses);\n\n\t\t\t\t\t\treturn FreehandToolFsmState::Drawing;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresponses.add(DocumentMessage::DeselectAllLayers);\n\n\t\t\t\tlet parent = document.new_layer_bounding_artboard(input, viewport);\n\n\t\t\t\tlet node_type = resolve_network_node_type(\"Path\").expect(\"Path node does not exist\");\n\t\t\t\tlet node = node_type.default_node_template();\n\t\t\t\tlet nodes = vec![(NodeId(0), node)];\n\n\t\t\t\tlet layer = graph_modification_utils::new_custom(NodeId::new(), nodes, parent, responses);\n\t\t\t\ttool_options.drawing.fill.apply_fill(layer, responses);\n\t\t\t\ttool_options.drawing.apply_stroke_to_new_layer(layer, responses);\n\t\t\t\ttool_options.drawing.apply_stroke_order_to_new_layer(layer, responses);\n\t\t\t\ttool_data.layer = Some(layer);\n\t\t\t\ttool_data.new_layer_viewport_start = Some(input.mouse.position);\n\n\t\t\t\t// Position the layer at the initial mouse position via Transform\n\t\t\t\tresponses.add(DeferMessage::AfterGraphRun {\n\t\t\t\t\tmessages: vec![translation_transform_set(document, layer, input.mouse.position), NodeGraphMessage::RunDocumentGraph.into()],\n\t\t\t\t});\n\n\t\t\t\tFreehandToolFsmState::Drawing\n\t\t\t}\n\t\t\t(FreehandToolFsmState::Drawing, FreehandToolMessage::PointerMove) => {","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/tool/tool_messages/freehand_tool.rs#L283-L319","documentation":"When a freehand stroke starts on empty space, the tool creates a new layer whose root is the built-in 'Path' network node, resolved by string name via resolve_network_node_type(\"Path\"). This consults DOCUMENT_NODE_TYPES with a DefinitionIdentifier::Network(\"Path\") key; the expect panics if no network-node definition is registered under that exact name. Unlike proto nodes, network nodes are pure editor-side structural definitions, so a miss almost always means the definition list was edited and 'Path' was renamed or dropped. The panic occurs on the first click/drag of a freehand path in a document.","triggerScenarios":"Freehand tool click that is not extending an existing path: the FSM calls DocumentMessage::DeselectAllLayers, then resolve_network_node_type(\"Path\").expect(\"Path node does not exist\") followed by default_node_template() to seed the new custom layer.","commonSituations":"Renaming the Path network node definition (e.g., localization or renaming passes) without updating the three tool call sites that hardcode \"Path\"; deleting the Path definition because a refactor moved path storage elsewhere; typos introduced when the string was duplicated instead of shared as a constant.","solutions":["Check the registry key: call collect_node_types() or inspect document_node_definitions() for a Network definition named exactly \"Path\".","Replace the hardcoded \"Path\" literals in freehand_tool.rs, pen_tool.rs, and spline_tool.rs with a shared constant that is defined next to the node definition, so rename and call site cannot drift.","If the node was renamed, update the definition name back or add the new name to the registry under the old key.","If Path was intentionally removed, return early from the tool transition and surface a warning instead of expecting."],"exampleFix":"// before\nlet node_type = resolve_network_node_type(\"Path\").expect(\"Path node does not exist\");\nlet node = node_type.default_node_template();\n\n// after (shared constant defined where the node is registered)\nlet node_type = resolve_network_node_type(PATH_NODE_NAME).expect(\"Path node can't be found\");\nlet node = node_type.default_node_template();","handlingStrategy":"validation","validationCode":"fn path_node_registered() -> bool {\n\tresolve_network_node_type(\"Path\").is_some()\n}\n\nif path_node_registered() {\n\tlet node = resolve_network_node_type(\"Path\").unwrap().default_node_template();\n\t// proceed with layer creation\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Define the Path node name once as a shared constant used by both the registry and the freehand/pen/spline tools.","Search for resolve_network_node_type(\"Path\") across the repo before renaming any network node definition.","Include a 'draw a freehand path' step in release smoke tests to catch registry drift early."],"tags":["rust","graphite-editor","node-registry","expect-panic","freehand-tool","network-node","string-key"],"backgroundTag":"static-registry-lookup-failed","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}