{"record":{"id":"b75d978922627971","repo":"GraphiteEditor/Graphite","slug":"stroke-node-does-not-exist","errorCode":null,"errorMessage":"Stroke node does not exist","messagePattern":"Stroke node does not exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/portfolio/document/graph_operation/utility_types.rs","lineNumber":172,"sourceCode":"\t\tlet shape = resolve_network_node_type(\"Path\")\n\t\t\t.expect(\"Path node does not exist\")\n\t\t\t.node_template_input_override([None, Some(NodeInput::value(TaggedValue::VectorModification(modification), false))]);\n\t\tlet shape_id = NodeId::new();\n\t\tself.network_interface.insert_node(shape_id, shape, &[]);\n\t\tself.network_interface.move_node_to_chain_start(&shape_id, layer, &[], self.import);\n\n\t\tif include_transform {\n\t\t\tlet transform = resolve_proto_node_type(graphene_std::transform_nodes::transform::IDENTIFIER)\n\t\t\t\t.expect(\"Transform node does not exist\")\n\t\t\t\t.default_node_template();\n\t\t\tlet transform_id = NodeId::new();\n\t\t\tself.network_interface.insert_node(transform_id, transform, &[]);\n\t\t\tself.network_interface.move_node_to_chain_start(&transform_id, layer, &[], self.import);\n\t\t}\n\n\t\tif include_stroke {\n\t\t\tlet stroke = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER)\n\t\t\t\t.expect(\"Stroke node does not exist\")\n\t\t\t\t.default_node_template();\n\t\t\tlet stroke_id = NodeId::new();\n\t\t\tself.network_interface.insert_node(stroke_id, stroke, &[]);\n\t\t\tself.network_interface.move_node_to_chain_start(&stroke_id, layer, &[], self.import);\n\t\t}\n\n\t\tif include_fill {\n\t\t\tlet fill = resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER)\n\t\t\t\t.expect(\"Fill node does not exist\")\n\t\t\t\t.default_node_template();\n\t\t\tlet fill_id = NodeId::new();\n\t\t\tself.network_interface.insert_node(fill_id, fill, &[]);\n\t\t\tself.network_interface.move_node_to_chain_start(&fill_id, layer, &[], self.import);\n\t\t}\n\t}\n\n\tpub fn insert_text(&mut self, text: String, font: Font, typesetting: TypesettingConfig, layer: LayerNodeIdentifier) {\n\t\tlet font_resource_id = ResourceId::new();","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/portfolio/document/graph_operation/utility_types.rs#L154-L190","documentation":"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.","triggerScenarios":"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.","commonSituations":"Refactors of `graphene_std::vector_nodes`; changing the stroke node's IDENTIFIER; dropping registry entries during definition-file merges.","solutions":["Verify the registry entry for the `stroke` proto node identifier.","Fix identifier/registry drift on whichever side changed.","Handle `None` by logging and skipping just the stroke insertion (fill/transform can proceed).","Cover this identifier in automated registry checks."],"exampleFix":"// before\nlet stroke = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER)\n    .expect(\"Stroke node does not exist\")\n    .default_node_template();\n\n// after\nif let Some(stroke_def) = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER) {\n    let stroke = stroke_def.default_node_template();\n    let stroke_id = NodeId::new();\n    self.network_interface.insert_node(stroke_id, stroke, &[]);\n    self.network_interface.move_node_to_chain_start(&stroke_id, layer, &[], self.import);\n} else {\n    log::error!(\"Stroke proto node not registered; inserting vector without stroke node\");\n}","handlingStrategy":"validation","validationCode":"// Before inserting stroked vector geometry:\nif document_node_definitions::resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER).is_none() {\n    log::error!(\"Stroke node not registered; inserting without stroke\");\n}","typeGuard":"fn stroke_node_registered() -> bool {\n    document_node_definitions::resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER).is_some()\n}","tryCatchPattern":"// Rust has no try/catch; degrade to inserting without the stroke node:\nif let Some(def) = resolve_proto_node_type(graphene_std::vector_nodes::stroke::IDENTIFIER) {\n    // insert stroke node\n} else {\n    log::error!(\"Stroke missing; vector inserted without stroke\");\n}","preventionTips":["Include vector_nodes identifiers in registry-completeness tests","Keep include_stroke/include_fill flags paired with Option-based insert logic","Synchronize renames across crates","Prefer let-else over expect in chain builders"],"tags":["rust","panic","expect","node-registry","proto-node","stroke-node","vector-insert","graphite"],"backgroundTag":"node-definition-not-found","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}