{"record":{"id":"c56b2f763668cfaf","repo":"influxdata/influxdb","slug":"there-should-not-already-be-a-node","errorCode":null,"errorMessage":"there should not already be a node","messagePattern":"there should not already be a node","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"influxdb3_catalog/src/catalog/versions/v2.rs","lineNumber":1732,"sourceCode":"                            .update(node_batch.node_catalog_id, node)\n                            .expect(\"existing node should update\");\n                    } else {\n                        let new_node = Arc::new(NodeDefinition {\n                            node_id: Arc::clone(node_id),\n                            node_catalog_id: node_batch.node_catalog_id,\n                            instance_id: Arc::clone(instance_id),\n                            mode: mode.clone(),\n                            core_count: *core_count,\n                            state: NodeState::Running {\n                                registered_time_ns: *registered_time_ns,\n                            },\n                            conn_info: conn_info.as_ref().map(|s| Arc::from(s.as_str())),\n                            cli_params: cli_params.as_ref().map(|s| Arc::from(s.as_str())),\n                            row_delete_predicate_version: *row_delete_predicate_version,\n                        });\n                        self.nodes\n                            .insert(node_batch.node_catalog_id, new_node)\n                            .expect(\"there should not already be a node\");\n                    }\n                    true\n                }\n                NodeCatalogOp::StopNode(StopNodeLog {\n                    stopped_time_ns, ..\n                }) => match self.nodes.get_by_id(&node_batch.node_catalog_id) {\n                    Some(mut new_node) => {\n                        let n = Arc::make_mut(&mut new_node);\n                        n.state = NodeState::Stopped {\n                            stopped_time_ns: *stopped_time_ns,\n                        };\n                        self.nodes\n                            .update(node_batch.node_catalog_id, new_node)\n                            .expect(\"there should be a node to update\");\n                        true\n                    }\n                    None => {\n                        warn!(","sourceCodeStart":1714,"sourceCodeEnd":1750,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_catalog/src/catalog/versions/v2.rs#L1714-L1750","documentation":"A panic from `.expect()` when inserting a brand-new NodeDefinition in the else-branch of CreateNode replay. The code believes no node with this node_catalog_id exists and calls `insert()`, but the repository's insert returned a conflict/None, i.e. a node with that id already exists. It guards against duplicate node ids corrupting the node catalog.","triggerScenarios":"Replaying a CreateNode batch whose node_catalog_id collides with an already-present node — e.g. duplicate operations in the batch log, or a replay that re-applies an operation already applied to the repository.","commonSituations":"Double-replayed WAL segments after an unclear shutdown, snapshot+WAL overlap causing the same create to be applied twice, or a duplicated batch produced by a buggy writer.","solutions":["Deduplicate node batches before applying; make create idempotent by checking `get_by_id` first.","Audit the WAL for duplicate CreateNode entries covering the same node_catalog_id.","If snapshot and WAL overlap, fix the snapshot/compaction boundaries so operations aren't replayed twice.","Replace the expect with a defensive check that logs and skips or converts to update on collision."],"exampleFix":"// before\nself.nodes\n    .insert(node_batch.node_catalog_id, new_node)\n    .expect(\"there should not already be a node\");\n// after\nif self.nodes.get_by_id(&node_batch.node_catalog_id).is_none() {\n    self.nodes\n        .insert(node_batch.node_catalog_id, new_node)\n        .expect(\"there should not already be a node\");\n} // else: idempotent no-op or update existing","handlingStrategy":"validation","validationCode":"assert!(nodes.get_by_id(&node_batch.node_catalog_id).is_none(), \"node already exists; make create idempotent\");","typeGuard":"fn is_new_node(nodes: &Nodes, id: NodeId) -> bool { nodes.get_by_id(&id).is_none() }","tryCatchPattern":null,"preventionTips":["Deduplicate node batches before applying them","Make CreateNode idempotent: skip or update when the id already exists","Fix snapshot/WAL boundaries to avoid double replay","Test replay with duplicated create operations"],"tags":["panic","catalog","duplicate-key","replay"],"backgroundTag":"internal-invariant-violation","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}