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

  1. Compare graphene_std::vector::spline::IDENTIFIER with the registry keys (print collect_node_types()) to spot rename drift.
  2. Always reference the IDENTIFIER constant from the defining crate instead of a string literal so renames propagate at compile time.
  3. If the spline node was deliberately removed, disable the spline tool entry when the lookup returns None rather than expecting.
  4. 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

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


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/97216f2e0bb3e1d6. Report an issue: GitHub.