GraphiteEditor/Graphite · error
Text to Vector node does not exist
Error message
Text to Vector node does not exist
What it means
Panics when `resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER)` returns `None` in `insert_text`. Every text layer is built as the chain `Text -> Text to Vector -> Transform -> Fill -> layer`; the Text to Vector proto node rasterizes/converts the run layout into vector geometry. The expect asserts its definition exists in the static `DOCUMENT_NODE_TYPES` registry.
Source
Thrown at editor/src/messages/portfolio/document/graph_operation/utility_types.rs:208
let font_resource_id = ResourceId::new();
let text = resolve_proto_node_type(graphene_std::text::text::IDENTIFIER)
.expect("Text node does not exist")
.node_template_input_override([
Some(NodeInput::value(TaggedValue::None, false)),
Some(NodeInput::value(TaggedValue::String(text), false)),
Some(NodeInput::value(TaggedValue::Resource(font_resource_id), false)),
Some(NodeInput::value(TaggedValue::F64(typesetting.font_size), false)),
Some(NodeInput::value(TaggedValue::F64(typesetting.line_height_ratio), false)),
Some(NodeInput::value(TaggedValue::F64(typesetting.letter_spacing), false)),
Some(NodeInput::value(TaggedValue::F64(typesetting.letter_tilt), false)),
Some(NodeInput::value(TaggedValue::Bool(typesetting.max_width.is_some()), false)),
Some(NodeInput::value(TaggedValue::F64(typesetting.max_width.unwrap_or(100.)), false)),
Some(NodeInput::value(TaggedValue::Bool(typesetting.max_height.is_some()), false)),
Some(NodeInput::value(TaggedValue::F64(typesetting.max_height.unwrap_or(100.)), false)),
Some(NodeInput::value(TaggedValue::TextAlign(typesetting.align), false)),
]);
let text_to_vector = resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER)
.expect("Text to Vector node does not exist")
.default_node_template();
let transform = resolve_proto_node_type(graphene_std::transform_nodes::transform::IDENTIFIER)
.expect("Transform node does not exist")
.default_node_template();
let fill = resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER)
.expect("Fill node does not exist")
.default_node_template();
// Build the chain `Text -> Text to Vector -> Transform -> Fill -> layer`
let text_id = NodeId::new();
self.network_interface.insert_node(text_id, text, &[]);
self.network_interface.move_node_to_chain_start(&text_id, layer, &[], self.import);
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);View on GitHub (pinned to c507b35645)
Solutions
- Confirm the registry entry for `text_to_vector` exists and matches the current IDENTIFIER constant.
- Fix the drift: restore the constant's value or re-add the definition.
- Handle `None` with a logged early return so no partial text chain is inserted.
- Cover this identifier in registry-completeness tests.
Example fix
// before
let text_to_vector = resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER)
.expect("Text to Vector node does not exist")
.default_node_template();
// after
let Some(text_to_vector) = resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER).map(|d| d.default_node_template()) else {
log::error!("Text to Vector proto node not registered; cannot create text layer");
return;
}; Defensive patterns
Strategy: validation
Validate before calling
// Before creating a text layer:
if document_node_definitions::resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER).is_none() {
log::error!("Text to Vector node not registered; text tool unavailable");
return;
} Type guard
fn text_to_vector_registered() -> bool {
document_node_definitions::resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER).is_some()
} Try / catch
// Rust has no try/catch; branch on the Option:
let Some(ttv_def) = resolve_proto_node_type(graphene_std::text::text_to_vector::IDENTIFIER) else {
log::error!("Text to Vector missing; aborting text layer creation");
return;
}; Prevention
- Batch-resolve the full text chain before mutating the graph
- Include text_to_vector in registry tests
- Register definitions atomically with node moves
- Use let-else over expect
When it happens
Trigger: Creating a text layer. Fires when the `text_to_vector` IDENTIFIER is absent from the registry — the node was renamed or moved within `graphene_std::text`, or its definition entry was dropped.
Common situations: Text subsystem refactors; identifier renames; registry omissions when nodes are added or merged.
Related errors
- Text node does not exist
- Solidify Stroke node should exist
- Boolean node does not exist
- Morph node does not exist
- Auto-Tangents node does not exist
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/b7fe5921381c8e13.
Report an issue: GitHub.