GraphiteEditor/Graphite · error
Color Value node does not exist
Error message
Color Value node does not exist
What it means
Panics when `resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER)` returns `None` in `insert_color_value`. Paint tools attach a Color Value node (fed into a layer's paint attachment input) to produce solid colors; the proto-node definition must be registered in the static `DOCUMENT_NODE_TYPES` registry. The expect is the standard registry-drift tripwire for the `color_value` identifier.
Source
Thrown at editor/src/messages/portfolio/document/graph_operation/utility_types.rs:239
self.responses.add(DocumentMessage::Resource(ResourceMessage::AddFont { resource_id: font_resource_id, font }));
let text_to_vector_id = NodeId::new();
self.network_interface.insert_node(text_to_vector_id, text_to_vector, &[]);
self.network_interface.move_node_to_chain_start(&text_to_vector_id, layer, &[], self.import);
let transform_id = NodeId::new();
self.network_interface.insert_node(transform_id, transform, &[]);
self.network_interface.move_node_to_chain_start(&transform_id, layer, &[], self.import);
let fill_id = NodeId::new();
self.network_interface.insert_node(fill_id, fill, &[]);
self.network_interface.move_node_to_chain_start(&fill_id, layer, &[], self.import);
}
pub fn insert_color_value(&mut self, color: Color, layer: LayerNodeIdentifier, attachment_input: InputConnector) -> NodeId {
let color_value = resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER)
.expect("Color Value node does not exist")
.node_template_input_override([Some(NodeInput::value(TaggedValue::None, false)), Some(NodeInput::value(TaggedValue::Color(color), false))]);
let color_value_id = NodeId::new();
self.network_interface.insert_node(color_value_id, color_value, &[]);
self.start_paint_chain(&color_value_id, layer, attachment_input);
color_value_id
}
/// Clear the whole-expanse paint one tool left on a layer so the other can start its own chain there.
/// Severing at the attachment detaches the layer from whatever the walk stopped at, which is the only part a node
/// the rest of the graph also draws from is subjected to, since such a node is never among those deleted.
fn clear_paint_chain(&mut self, paint_chain: &ReplaceablePaintChain) {
self.network_interface.disconnect_input(&paint_chain.attachment_input, &[]);
if !paint_chain.nodes.is_empty() {
self.network_interface.delete_nodes(paint_chain.nodes.clone(), false, &[]);
}View on GitHub (pinned to c507b35645)
Solutions
- Verify the registry contains a definition matching `graphene_std::math_nodes::color_value::IDENTIFIER`.
- Repair the drift: restore the IDENTIFIER value or re-add the registry entry.
- Handle `None` with a logged early return so the paint operation is skipped rather than crashing mid-stroke.
- Cover this identifier in registry-completeness tests.
Example fix
// before
let color_value = resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER)
.expect("Color Value node does not exist")
.node_template_input_override([...]);
// after
let Some(cv_def) = resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER) else {
log::error!("Color Value proto node not registered; skipping paint insert");
return NodeId::new();
};
let color_value = cv_def.node_template_input_override([...]); Defensive patterns
Strategy: validation
Validate before calling
// Before a paint tool applies a color:
if document_node_definitions::resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER).is_none() {
log::error!("Color Value node not registered; paint disabled");
return;
} Type guard
fn color_value_registered() -> bool {
document_node_definitions::resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER).is_some()
} Try / catch
// Rust has no try/catch; branch on the Option before starting the paint chain:
let Some(cv_def) = resolve_proto_node_type(graphene_std::math_nodes::color_value::IDENTIFIER) else {
log::error!("Color Value missing; skipping paint");
return;
}; Prevention
- Include math_nodes identifiers in registry-completeness tests
- Guard paint flows so a missing node skips painting instead of crashing mid-stroke
- Synchronize math_nodes renames with the registry
- Use let-else over expect in paint helpers
When it happens
Trigger: A tool applying a solid fill/stroke color to a layer via `insert_color_value` (then `start_paint_chain` wires it to the attachment input). Fires when the `math_nodes::color_value` IDENTIFIER is missing from the registry — node renamed, moved out of `math_nodes`, or definition never added.
Common situations: Refactors of `graphene_std::math_nodes`; renaming the Color Value node or its identifier; adding math nodes without registering their editor-side definitions.
Related errors
- Solidify Stroke node should exist
- Boolean node does not exist
- Morph node does not exist
- Auto-Tangents node does not exist
- Transform node does not exist
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/641fb4f6759c6c53.
Report an issue: GitHub.