GraphiteEditor/Graphite · error

Stroke node does not exist

Error message

Stroke node does not exist

What it means

Panics when `resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER)` returns `None` in `insert_vector` (only when `include_stroke` is true), which appends a Stroke node to newly inserted vector geometry. The static registry must contain the `stroke` proto-node definition; the expect is the usual registry-invariant assertion.

Source

Thrown at editor/src/messages/portfolio/document/graph_operation/utility_types.rs:172

		let shape = resolve_network_node_type("Path")
			.expect("Path node does not exist")
			.node_template_input_override([None, Some(NodeInput::value(TaggedValue::VectorModification(modification), false))]);
		let shape_id = NodeId::new();
		self.network_interface.insert_node(shape_id, shape, &[]);
		self.network_interface.move_node_to_chain_start(&shape_id, layer, &[], self.import);

		if include_transform {
			let transform = resolve_proto_node_type(graphene_std::transform_nodes::transform::IDENTIFIER)
				.expect("Transform node does not exist")
				.default_node_template();
			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);
		}

		if include_stroke {
			let stroke = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER)
				.expect("Stroke node does not exist")
				.default_node_template();
			let stroke_id = NodeId::new();
			self.network_interface.insert_node(stroke_id, stroke, &[]);
			self.network_interface.move_node_to_chain_start(&stroke_id, layer, &[], self.import);
		}

		if include_fill {
			let fill = resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER)
				.expect("Fill node does not exist")
				.default_node_template();
			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_text(&mut self, text: String, font: Font, typesetting: TypesettingConfig, layer: LayerNodeIdentifier) {
		let font_resource_id = ResourceId::new();

View on GitHub (pinned to c507b35645)

Solutions

  1. Verify the registry entry for the `stroke` proto node identifier.
  2. Fix identifier/registry drift on whichever side changed.
  3. Handle `None` by logging and skipping just the stroke insertion (fill/transform can proceed).
  4. Cover this identifier in automated registry checks.

Example fix

// before
let stroke = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER)
    .expect("Stroke node does not exist")
    .default_node_template();

// after
if let Some(stroke_def) = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER) {
    let stroke = stroke_def.default_node_template();
    let stroke_id = NodeId::new();
    self.network_interface.insert_node(stroke_id, stroke, &[]);
    self.network_interface.move_node_to_chain_start(&stroke_id, layer, &[], self.import);
} else {
    log::error!("Stroke proto node not registered; inserting vector without stroke node");
}
Defensive patterns

Strategy: validation

Validate before calling

// Before inserting stroked vector geometry:
if document_node_definitions::resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER).is_none() {
    log::error!("Stroke node not registered; inserting without stroke");
}

Type guard

fn stroke_node_registered() -> bool {
    document_node_definitions::resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER).is_some()
}

Try / catch

// Rust has no try/catch; degrade to inserting without the stroke node:
if let Some(def) = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER) {
    // insert stroke node
} else {
    log::error!("Stroke missing; vector inserted without stroke");
}

Prevention

When it happens

Trigger: Inserting vector geometry that has stroke styling (e.g. pasting stroked paths, shape tools preserving stroke). Fires when the `vector_nodes::stroke` IDENTIFIER is absent from `DOCUMENT_NODE_TYPES` — rename, module move, or unregistered definition.

Common situations: Refactors of `graphene_std::vector_nodes`; changing the stroke node's IDENTIFIER; dropping registry entries during definition-file merges.

Related errors


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/b75d978922627971. Report an issue: GitHub.