{"record":{"id":"1e1a65c4a4b99b1b","repo":"GraphiteEditor/Graphite","slug":"path-node-does-not-exist","errorCode":null,"errorMessage":"Path node does not exist","messagePattern":"Path node does not exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/portfolio/document/graph_operation/utility_types.rs","lineNumber":141,"sourceCode":"\tpub fn insert_control_path_data(&mut self, layer: LayerNodeIdentifier) -> NodeId {\n\t\t// Add Origins to Polyline node first (will be pushed deepest in the chain)\n\t\tlet origins_to_polyline = resolve_network_node_type(\"Origins to Polyline\")\n\t\t\t.expect(\"Origins to Polyline node does not exist\")\n\t\t\t.default_node_template();\n\t\tlet origins_to_polyline_id = NodeId::new();\n\t\tself.network_interface.insert_node(origins_to_polyline_id, origins_to_polyline, &[]);\n\t\tself.network_interface.move_node_to_chain_start(&origins_to_polyline_id, layer, &[], self.import);\n\n\t\t// Add Auto-Tangents node (between Origins to Polyline and Path), with spread=1 and preserve_existing=false\n\t\tlet auto_tangents = resolve_proto_node_type(graphene_std::vector::auto_tangents::IDENTIFIER)\n\t\t\t.expect(\"Auto-Tangents node does not exist\")\n\t\t\t.node_template_input_override([None, Some(NodeInput::value(TaggedValue::F64(1.), false)), Some(NodeInput::value(TaggedValue::Bool(false), false))]);\n\t\tlet auto_tangents_id = NodeId::new();\n\t\tself.network_interface.insert_node(auto_tangents_id, auto_tangents, &[]);\n\t\tself.network_interface.move_node_to_chain_start(&auto_tangents_id, layer, &[], self.import);\n\n\t\t// Add Path node to chain start (closest to the Merge node)\n\t\tlet path = resolve_network_node_type(\"Path\").expect(\"Path node does not exist\").default_node_template();\n\t\tlet path_id = NodeId::new();\n\t\tself.network_interface.insert_node(path_id, path, &[]);\n\t\tself.network_interface.move_node_to_chain_start(&path_id, layer, &[], self.import);\n\n\t\tpath_id\n\t}\n\n\tpub fn insert_vector(&mut self, subpaths: Vec<Subpath<PointId>>, layer: LayerNodeIdentifier, include_transform: bool, include_fill: bool, include_stroke: bool) {\n\t\t// Build a VectorModification that reproduces the geometry (same format the Pen tool uses)\n\t\tlet vector = Vector::from_subpaths(subpaths, true);\n\t\tlet modification = Box::new(VectorModification::create_from_vector(&vector));\n\n\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);","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/portfolio/document/graph_operation/utility_types.rs#L123-L159","documentation":"Panics when `resolve_network_node_type(\"Path\")` returns `None` at the end of `insert_control_path_data` (the Path node is added chain-start, closest to the layer's Merge node). The `\"Path\"` network-node definition must exist in the static registry; this expect asserts its presence. Because Path is one of the most fundamental node types, hitting this panic indicates wholesale registry breakage rather than an isolated rename.","triggerScenarios":"Creating a control path for a layer. Fires when the `\"Path\"` key is missing from `DOCUMENT_NODE_TYPES` — e.g. the registry-generation macro broke, the entry was renamed, or a build config excluded core definitions.","commonSituations":"Major refactors of `document_node_definitions.rs`; rebase conflicts that silently drop entries; typos when the key string is duplicated at many call sites (this is one of several `\"Path\"` lookups in the file).","solutions":["Check that `\"Path\"` exists in `DOCUMENT_NODE_TYPES`; restore the entry if missing.","Align the string with the registry key if the node was renamed (and audit the other `\"Path\"` call sites in this file).","Replace the expect with logged `Option` handling, aborting the control-path insert on `None`.","Add a smoke test that resolves every bare string used in `utility_types.rs`."],"exampleFix":"// before\nlet path = resolve_network_node_type(\"Path\").expect(\"Path node does not exist\").default_node_template();\n\n// after\nlet Some(path_def) = resolve_network_node_type(\"Path\") else {\n    log::error!(\"Path node definition not registered; aborting control path insert\");\n    return NodeId::new();\n};\nlet path = path_def.default_node_template();","handlingStrategy":"validation","validationCode":"// Before building a control path:\nif document_node_definitions::resolve_network_node_type(\"Path\").is_none() {\n    log::error!(\"Path node not registered; control path unavailable\");\n    return;\n}","typeGuard":"fn path_node_available() -> bool {\n    document_node_definitions::resolve_network_node_type(\"Path\").is_some()\n}","tryCatchPattern":"// Rust has no try/catch; branch on the Option:\nlet Some(path_def) = resolve_network_node_type(\"Path\") else {\n    log::error!(\"Path node missing\");\n    return;\n};","preventionTips":["Treat the Path key as core infrastructure — smoke test it in every CI run","Extract one shared constant for \"Path\" and use it at all call sites","Audit duplicated string keys after any definitions-file refactor","Alias renamed keys instead of breaking lookups"],"tags":["rust","panic","expect","node-registry","string-lookup","path-node","control-path","graphite"],"backgroundTag":"node-definition-not-found","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}