GraphiteEditor/Graphite · error
Blend node does not exist
Error message
Blend node does not exist
What it means
Panics when the string lookup `resolve_network_node_type("Blend")` returns `None` in `insert_blend_data`. The Blend node (step-count blend between shapes) is inserted at the chain start of a layer; the definition must exist in `DOCUMENT_NODE_TYPES` under exactly `"Blend"`. This is a static-invariant expect — it cannot fire unless the registry and this call site disagree on the key.
Source
Thrown at editor/src/messages/portfolio/document/graph_operation/utility_types.rs:100
LayerNodeIdentifier::new(new_id, self.network_interface)
}
pub fn insert_boolean_data(&mut self, operation: graphene_std::vector::misc::BooleanOperation, layer: LayerNodeIdentifier) {
let boolean = resolve_proto_node_type(graphene_std::path_bool_nodes::boolean_operation::IDENTIFIER)
.expect("Boolean node does not exist")
.node_template_input_override([
Some(NodeInput::type_default(list!(Graphic), true)),
Some(NodeInput::value(TaggedValue::BooleanOperation(operation), false)),
]);
let boolean_id = NodeId::new();
self.network_interface.insert_node(boolean_id, boolean, &[]);
self.network_interface.move_node_to_chain_start(&boolean_id, layer, &[], self.import);
}
pub fn insert_blend_data(&mut self, layer: LayerNodeIdentifier, count: f64) -> NodeId {
let blend = resolve_network_node_type("Blend")
.expect("Blend node does not exist")
.node_template_input_override([Some(NodeInput::type_default(list!(Graphic), true)), Some(NodeInput::value(TaggedValue::F64(count), false))]);
let blend_id = NodeId::new();
self.network_interface.insert_node(blend_id, blend, &[]);
self.network_interface.move_node_to_chain_start(&blend_id, layer, &[], self.import);
blend_id
}
pub fn insert_morph_data(&mut self, layer: LayerNodeIdentifier) -> NodeId {
let morph = resolve_proto_node_type(graphene_std::vector::morph::IDENTIFIER)
.expect("Morph node does not exist")
.node_template_input_override([Some(NodeInput::type_default(list!(Graphic), true)), Some(NodeInput::value(TaggedValue::F64(0.5), false))]);
let morph_id = NodeId::new();
self.network_interface.insert_node(morph_id, morph, &[]);
self.network_interface.move_node_to_chain_start(&morph_id, layer, &[], self.import);
View on GitHub (pinned to c507b35645)
Solutions
- Verify the `"Blend"` key exists in `DOCUMENT_NODE_TYPES` and its definition is intact.
- Align the string here with the actual registry key (or add an alias) if the node was renamed.
- Replace the expect with `Option` handling that logs and returns `NodeId::new()`-free early exit (return before inserting anything).
- Centralize these magic strings as constants shared with the registry definition.
Example fix
// before
let blend = resolve_network_node_type("Blend")
.expect("Blend node does not exist")
.node_template_input_override([...]);
// after
let Some(blend_def) = resolve_network_node_type("Blend") else {
log::error!("Blend node definition not registered; aborting blend insert");
return NodeId::new(); // caller must treat this as failure; better: return Option<NodeId>
};
let blend = blend_def.node_template_input_override([...]); Defensive patterns
Strategy: validation
Validate before calling
// Before the blend operation:
if document_node_definitions::resolve_network_node_type("Blend").is_none() {
log::error!("Blend node not registered; command unavailable");
return;
} Type guard
fn blend_node_available() -> bool {
document_node_definitions::resolve_network_node_type("Blend").is_some()
} Try / catch
// Rust has no try/catch; branch on the Option:
let Some(blend_def) = resolve_network_node_type("Blend") else {
log::error!("Blend node missing");
return;
}; Prevention
- Use shared constants instead of inline "Blend" strings
- Test blend flows whenever the registry file changes
- Alias old keys when renaming
- Return Option<NodeId> from insert helpers so callers can handle failure
When it happens
Trigger: Running the Blend operation on layers (`insert_blend_data` with a step count). Fires when the `"Blend"` key is missing from `DOCUMENT_NODE_TYPES`: renamed key/typo, deleted definition, or feature-gated registry entry.
Common situations: Registry refactors that rename display-name keys; merging branches where one side removed or renamed Blend; typos introduced when call sites are hand-edited from `"Blend"` to a new name.
Related errors
- Merge node
- Node
- Origins to Polyline node does not exist
- Path node does not exist
- Solidify Stroke node should exist
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/f419954705c42298.
Report an issue: GitHub.