{"record":{"id":"5ee2ee170b4f791e","repo":"GraphiteEditor/Graphite","slug":"fill-node-does-not-exist","errorCode":null,"errorMessage":"Fill node does not exist","messagePattern":"Fill node does not exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/portfolio/document/graph_operation/utility_types.rs","lineNumber":181,"sourceCode":"\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();\n\t\tlet text = resolve_proto_node_type(graphene_std::text::text::IDENTIFIER)\n\t\t\t.expect(\"Text node does not exist\")\n\t\t\t.node_template_input_override([\n\t\t\t\tSome(NodeInput::value(TaggedValue::None, false)),\n\t\t\t\tSome(NodeInput::value(TaggedValue::String(text), false)),\n\t\t\t\tSome(NodeInput::value(TaggedValue::Resource(font_resource_id), false)),\n\t\t\t\tSome(NodeInput::value(TaggedValue::F64(typesetting.font_size), false)),\n\t\t\t\tSome(NodeInput::value(TaggedValue::F64(typesetting.line_height_ratio), false)),\n\t\t\t\tSome(NodeInput::value(TaggedValue::F64(typesetting.letter_spacing), false)),","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/portfolio/document/graph_operation/utility_types.rs#L163-L199","documentation":"Panics when `resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER)` returns `None` in `insert_vector` (only when `include_fill` is true), which appends a Fill node to newly inserted vector geometry. The `fill` proto-node definition must exist in the static `DOCUMENT_NODE_TYPES` registry; the expect asserts that invariant at the last step of vector insertion.","triggerScenarios":"Inserting vector geometry that has fill styling. Fires when the `vector_nodes::fill` IDENTIFIER resolves to no registry entry — renamed identifier, module reorganization, or a dropped/unregistered definition.","commonSituations":"Renaming the Fill node or its IDENTIFIER; moving nodes out of `graphene_std::vector_nodes`; registry-list omissions after adding or merging definitions.","solutions":["Check the registry contains a definition for the `fill` IDENTIFIER.","Repair the drift (restore the constant or re-add the entry).","Handle `None` by logging and skipping the fill insertion only.","Include this identifier in registry-completeness tests."],"exampleFix":"// before\nlet fill = resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER)\n    .expect(\"Fill node does not exist\")\n    .default_node_template();\n\n// after\nif let Some(fill_def) = resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER) {\n    let fill = fill_def.default_node_template();\n    let fill_id = NodeId::new();\n    self.network_interface.insert_node(fill_id, fill, &[]);\n    self.network_interface.move_node_to_chain_start(&fill_id, layer, &[], self.import);\n} else {\n    log::error!(\"Fill proto node not registered; inserting vector without fill node\");\n}","handlingStrategy":"validation","validationCode":"// Before inserting filled vector geometry:\nif document_node_definitions::resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER).is_none() {\n    log::error!(\"Fill node not registered; inserting without fill\");\n}","typeGuard":"fn fill_node_registered() -> bool {\n    document_node_definitions::resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER).is_some()\n}","tryCatchPattern":"// Rust has no try/catch; degrade to inserting without the fill node:\nif let Some(def) = resolve_proto_node_type(graphene_std::vector_nodes::fill::IDENTIFIER) {\n    // insert fill node\n} else {\n    log::error!(\"Fill missing; vector inserted without fill\");\n}","preventionTips":["Include fill identifiers in registry tests","Make optional nodes fail soft so geometry insertion still succeeds","Register definitions atomically with node additions","Use let-else over expect"],"tags":["rust","panic","expect","node-registry","proto-node","fill-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"}