GraphiteEditor/Graphite · error
Spline node does not exist
Error message
Spline node does not exist
What it means
The spline tool's second node is the Spline proto node (graphene_std::vector::spline::IDENTIFIER), resolved via resolve_proto_node_type and expected to exist in the DOCUMENT_NODE_TYPES registry. This expect guards that the spline vector manipulation node compiled into graphene_std was registered under the same identifier the editor searches for. It fires together with the Path lookup when the spline tool first builds its layer graph, so a panic here means registry/build drift for the proto node specifically.
Source
Thrown at editor/src/messages/tool/tool_messages/spline_tool.rs:406
// Create new path in the selected layer when shift is down
if let (Some(layer), true) = (selected_layer, append_to_selected_layer) {
tool_data.current_layer = Some(layer);
let transform = document.metadata().transform_to_viewport(layer);
let position = transform.inverse().transform_point2(input.mouse.position);
tool_data.next_point = position;
return SplineToolFsmState::Drawing;
}
responses.add(DocumentMessage::DeselectAllLayers);
let parent = document.new_layer_bounding_artboard(input, viewport);
let path_node_type = resolve_network_node_type("Path").expect("Path node does not exist");
let path_node = path_node_type.default_node_template();
let spline_node_type = resolve_proto_node_type(graphene_std::vector::spline::IDENTIFIER).expect("Spline node does not exist");
let spline_node = spline_node_type.node_template_input_override([Some(NodeInput::node(NodeId(1), 0))]);
let nodes = vec![(NodeId(1), path_node), (NodeId(0), spline_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.current_layer = Some(layer);
tool_data.new_layer_viewport_start = Some(viewport_vec);
// Position the layer at the initial mouse position via Transform
responses.add(DeferMessage::AfterGraphRun {
messages: vec![translation_transform_set(document, layer, viewport_vec), NodeGraphMessage::RunDocumentGraph.into()],
});
SplineToolFsmState::Drawing
}
(SplineToolFsmState::Drawing, SplineToolMessage::DragStop) => {View on GitHub (pinned to c507b35645)
Solutions
- Compare graphene_std::vector::spline::IDENTIFIER with the registry keys (print collect_node_types()) to spot rename drift.
- Always reference the IDENTIFIER constant from the defining crate instead of a string literal so renames propagate at compile time.
- If the spline node was deliberately removed, disable the spline tool entry when the lookup returns None rather than expecting.
- cargo clean and rebuild after cross-crate node moves so the registration macros regenerate.
Example fix
// before
let spline_node_type = resolve_proto_node_type(graphene_std::vector::spline::IDENTIFIER).expect("Spline node does not exist");
// after
let Some(spline_node_type) = resolve_proto_node_type(graphene_std::vector::spline::IDENTIFIER) else {
log::error!("Spline proto node not registered; spline tool unavailable");
return SplineToolFsmState::Ready;
}; Defensive patterns
Strategy: validation
Validate before calling
fn spline_node_registered() -> bool {
resolve_proto_node_type(graphene_std::vector::spline::IDENTIFIER).is_some()
}
// before the first spline click:
if spline_node_registered() { /* create the spline layer */ } else { /* disable tool */ } Prevention
- Reference proto node identifiers via their crate constants; never inline identifier strings in tool code.
- Rebuild fully after moving node definitions between crates so registry registration macros regenerate.
- Include spline tool usage in post-registry-refactor smoke tests.
When it happens
Trigger: First spline click in a document: resolve_proto_node_type(graphene_std::vector::spline::IDENTIFIER).expect("Spline node does not exist") runs immediately after the Path lookup, then node_template_input_override wires the spline node's input to the Path node (NodeId(1), output 0).
Common situations: Renaming or moving the spline node's IDENTIFIER in graphene_std::vector without updating spline_tool.rs; dropping the spline node registration during vector-node refactors; cargo features excluding the spline implementation; stale mixed builds after moving node definitions between crates.
Related errors
- Brush node does not exist
- Path node does not exist
- Star node can't be found
- Path node does not exist
- Path node does not exist
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/97216f2e0bb3e1d6.
Report an issue: GitHub.