GraphiteEditor/Graphite · error
Path node does not exist
Error message
Path node does not exist
What it means
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.
Source
Thrown at editor/src/messages/tool/tool_messages/freehand_tool.rs:301
let mut selected_layers_except_artboards = selected_nodes.selected_layers_except_artboards(&document.network_interface);
let existing_layer = selected_layers_except_artboards.next().filter(|_| selected_layers_except_artboards.next().is_none());
if let Some(layer) = existing_layer {
tool_data.layer = Some(layer);
let transform = document.metadata().transform_to_viewport(layer);
let position = transform.inverse().transform_point2(input.mouse.position);
extend_path_with_next_segment(tool_data, position, false, responses);
return FreehandToolFsmState::Drawing;
}
}
responses.add(DocumentMessage::DeselectAllLayers);
let parent = document.new_layer_bounding_artboard(input, viewport);
let node_type = resolve_network_node_type("Path").expect("Path node does not exist");
let node = node_type.default_node_template();
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId::new(), nodes, parent, responses);
tool_options.drawing.fill.apply_fill(layer, responses);
tool_options.drawing.apply_stroke_to_new_layer(layer, responses);
tool_options.drawing.apply_stroke_order_to_new_layer(layer, responses);
tool_data.layer = Some(layer);
tool_data.new_layer_viewport_start = Some(input.mouse.position);
// Position the layer at the initial mouse position via Transform
responses.add(DeferMessage::AfterGraphRun {
messages: vec![translation_transform_set(document, layer, input.mouse.position), NodeGraphMessage::RunDocumentGraph.into()],
});
FreehandToolFsmState::Drawing
}
(FreehandToolFsmState::Drawing, FreehandToolMessage::PointerMove) => {View on GitHub (pinned to c507b35645)
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.
Example fix
// before
let node_type = resolve_network_node_type("Path").expect("Path node does not exist");
let node = node_type.default_node_template();
// after (shared constant defined where the node is registered)
let node_type = resolve_network_node_type(PATH_NODE_NAME).expect("Path node can't be found");
let node = node_type.default_node_template(); Defensive patterns
Strategy: validation
Validate before calling
fn path_node_registered() -> bool {
resolve_network_node_type("Path").is_some()
}
if path_node_registered() {
let node = resolve_network_node_type("Path").unwrap().default_node_template();
// proceed with layer creation
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Path node does not exist
- Path node does not exist
- Star node can't be found
- Brush node does not exist
- Spline node does not exist
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/9c3d9c3ee8b8dbcd.
Report an issue: GitHub.