GraphiteEditor/Graphite · critical
Spiral node can't be found
Error message
Spiral node can't be found
What it means
Spiral::create_node resolves the Spiral generator via DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::spiral::IDENTIFIER) and resolve_document_node_type(...).expect("Spiral node can't be found") (spiral_shape.rs:104). The resolver is a get on the static DOCUMENT_NODE_TYPES HashMap (document_node_definitions.rs:130/1484); None — hence the panic — means the Spiral node is unregistered under that identifier. It fires the first time the Spiral tool inserts its node (with the type/turns defaults computed just above).
Source
Thrown at editor/src/messages/tool/common_functionality/shapes/spiral_shape.rs:104
let (spiral_type, start_angle, a, outer_radius, turns, _) = extract_spiral_parameters(layer, document)?;
let b = calculate_growth_factor(a, turns, outer_radius, spiral_type);
let theta = turns * theta + start_angle.to_radians();
Some(viewport.transform_point2(spiral_point(theta, a, b, spiral_type)))
}
#[derive(Default)]
pub struct Spiral;
impl Spiral {
pub fn create_node(spiral_type: SpiralType, turns: f64) -> NodeTemplate {
let inner_radius = match spiral_type {
SpiralType::Archimedean => 0.,
SpiralType::Logarithmic => 0.1,
};
let identifier = DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::spiral::IDENTIFIER);
let node_type = resolve_document_node_type(&identifier).expect("Spiral node can't be found");
node_type.node_template_input_override([
None,
Some(NodeInput::value(TaggedValue::SpiralType(spiral_type), false)),
Some(NodeInput::value(TaggedValue::F64(turns), false)),
Some(NodeInput::value(TaggedValue::F64(0.), false)),
Some(NodeInput::value(TaggedValue::F64(inner_radius), false)),
Some(NodeInput::value(TaggedValue::F64(0.1), false)),
Some(NodeInput::value(TaggedValue::F64(90.), false)),
])
}
pub fn update_shape(
document: &DocumentMessageHandler,
ipp: &InputPreprocessorMessageHandler,
viewport: &ViewportMessageHandler,
layer: LayerNodeIdentifier,
shape_tool_data: &mut ShapeToolData,
responses: &mut VecDeque<Message>,View on GitHub (pinned to c507b35645)
Solutions
- Confirm the spiral identifier is registered by checking DOCUMENT_NODE_TYPES (grep its string in document_node_definitions.rs)
- Fix the identifier/registration mismatch and rebuild
- Use let-else so the spiral tool logs and skips layer creation instead of panicking
- Add Spiral to the cross-tool registry-drift test
Example fix
// before
let node_type = resolve_document_node_type(&identifier).expect("Spiral node can't be found");
// after
let Some(node_type) = resolve_document_node_type(&identifier) else {
log::error!("Spiral node definition missing from DOCUMENT_NODE_TYPES");
return None;
}; Defensive patterns
Strategy: validation
Validate before calling
fn spiral_node_available() -> bool {
document_node_definitions::resolve_document_node_type(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::spiral::IDENTIFIER)).is_some()
} Prevention
- Add Spiral to the shared registry-drift test covering all shape tools
- Note the 7-element override array here — the longest among shape tools and most likely to break when Spiral's inputs change
- Prefer graceful let-else handling in tool code; reserve expect for invariants the compiler cannot check but tests do
When it happens
Trigger: Drawing with the Spiral tool while generator_nodes::spiral::IDENTIFIER is absent from DOCUMENT_NODE_TYPES (renamed const, removed node, or edited registration list).
Common situations: Renaming/moving the spiral generator during refactors; Graphite upgrades re-namespacing generator nodes; feature-gated builds excluding spiral; stale 7-element override arrays after the node's inputs change (separate index panic at document_node_definitions.rs:1536).
Related errors
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/4b1174d95a7f95a8.
Report an issue: GitHub.