GraphiteEditor/Graphite · error
Solidify Stroke node should exist
Error message
Solidify Stroke node should exist
What it means
Panics when `document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER)` returns `None`. The function looks the node up in the static `DOCUMENT_NODE_TYPES` registry (document_node_definitions.rs:1480-1486); the Graphite editor assumes every proto node its handlers reference is registered there at build time. The expect is a static-invariant assertion: it can only fire if the registry and the `solidify_stroke` IDENTIFIER constant have drifted apart (rename, move, or missing registration).
Source
Thrown at editor/src/messages/portfolio/document/document_message_handler.rs:2746
new_folders.push(DocumentMessageHandler::group_layers(responses, insert_index, parent, group_folder_type, &mut self.network_interface));
}
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: new_folders });
}
}
/// For each selected layer, splits its fill and stroke into two stacked layers connected
/// to a shared `Solidify Stroke` node via two `Item at Index` nodes (indices 0 and 1).
/// Layers with only a stroke get just a `Solidify Stroke` added.
/// Layers with only a fill, or neither, are left untouched.
fn handle_expand_fill_stroke_on_selected_layers(&mut self, responses: &mut VecDeque<Message>) {
let selected_layers: Vec<LayerNodeIdentifier> = self.network_interface.selected_nodes().selected_layers(self.metadata()).collect();
if selected_layers.is_empty() {
return;
}
let solidify_stroke_definition = document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER).expect("Solidify Stroke node should exist");
let item_at_index_definition = document_node_definitions::resolve_proto_node_type(graphene_std::graphic::item_at_index::IDENTIFIER).expect("Item at Index node should exist");
let mut resulting_layers: Vec<NodeId> = Vec::new();
for layer in selected_layers {
if !self.network_interface.document_metadata().layer_vector_data.contains_key(&layer) {
resulting_layers.push(layer.to_node());
continue;
}
let appearance = self.network_interface.document_metadata().layer_appearance_attributes.get(&layer);
let has_fill = appearance.is_some_and(|appearance| appearance.has_painted_cover(Cover::Fill));
// A visible stroke needs both renderable geometry (non-zero weight) and paint that draws something
let has_stroke = appearance.is_some_and(|appearance| {
appearance.first_coverage_of(Cover::Stroke).is_some_and(|coverage| coverage.stroke_params().has_renderable_stroke())
&& appearance.first_paint_of(Cover::Stroke).is_some_and(|paint| !paint.is_guaranteed_fully_transparent())
});View on GitHub (pinned to c507b35645)
Solutions
- Confirm the registry entry exists: search `DOCUMENT_NODE_TYPES` / the generate-registry macro in `editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs` for the Solidify Stroke definition.
- If the node was renamed or moved, restore the old `IDENTIFIER` value in `graphene_std::vector::solidify_stroke` or update the call site to the new identifier.
- If this is a new node, add its `DocumentNodeDefinition` to the registry (correct `ProtoNodeIdentifier`, category, and template).
- Replace the `expect` with graceful `Option` handling (log and return) so a registry drift degrades instead of crashing the editor.
Example fix
// before
let solidify_stroke_definition = document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER).expect("Solidify Stroke node should exist");
// after
let Some(solidify_stroke_definition) = document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER) else {
log::error!("Solidify Stroke node definition is not registered; skipping expand fill/stroke");
return;
}; Defensive patterns
Strategy: validation
Validate before calling
// Before running the expand fill/stroke command, confirm the definitions exist:
let ok = [
graphene_std::vector::solidify_stroke::IDENTIFIER,
graphene_std::graphic::item_at_index::IDENTIFIER,
].iter().all(|id| document_node_definitions::resolve_proto_node_type(*id).is_some());
if !ok {
log::error!("Expand Fill/Stroke unavailable: required node definitions not registered");
return;
} Type guard
fn solidify_stroke_registered() -> bool {
document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER).is_some()
} Try / catch
// Rust has no try/catch; isolate the panic at a boundary if unavoidable:
let template = std::panic::catch_unwind(|| {
document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER)
.map(|d| d.default_node_template())
});
if template.is_err() {
log::error!("solidify stroke lookup panicked; registry is inconsistent");
} Prevention
- Add a startup/CI test that resolves every IDENTIFIER referenced by message handlers
- Never rename a proto node IDENTIFIER without grepping editor/src for its use sites
- Treat resolve_proto_node_type as fallible: log-and-return instead of expect in message handlers
- When adding a node, register its definition in the same commit that introduces the IDENTIFIER constant
When it happens
Trigger: Invoked from `handle_expand_fill_stroke_on_selected_layers`, i.e. the user runs the Expand Fill/Stroke command on one or more selected layers. The panic fires only when the `Solidify Stroke` proto node definition is absent from `DOCUMENT_NODE_TYPES` — e.g. the node was renamed in graphene_std, moved modules, its `IDENTIFIER` constant changed, or it was never added to the node registry list.
Common situations: Renaming a proto node struct or its `IDENTIFIER` without updating `document_node_definitions.rs`; moving `solidify_stroke` between crates/modules; adding a new node to graphene_std but forgetting the registry entry; builds where a feature flag excludes the node definition module.
Related errors
- Boolean node does not exist
- Morph node does not exist
- Auto-Tangents node does not exist
- Transform node does not exist
- Stroke node does not exist
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/1ae71c10d40d3ef9.
Report an issue: GitHub.