{"record":{"id":"4d3ce4398a39405b","repo":"TheAlgorithms/Go","slug":"node-has-too-many-keys","errorCode":null,"errorMessage":"node has too many keys","messagePattern":"node has too many keys","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"structure/tree/btree.go","lineNumber":50,"sourceCode":"\t}\n}\n\nfunc NewBTree[T constraints.Ordered](maxKeys int) *BTree[T] {\n\tif maxKeys <= 2 {\n\t\tpanic(\"Must be >= 3 keys\")\n\t}\n\treturn &BTree[T]{\n\t\troot:    nil,\n\t\tmaxKeys: maxKeys,\n\t}\n}\n\nfunc (node *BTreeNode[T]) Verify(tree *BTree[T]) {\n\tminKeys := minKeys(tree.maxKeys)\n\tif node != tree.root && node.numKeys < minKeys {\n\t\tpanic(\"node has too few keys\")\n\t} else if node.numKeys > tree.maxKeys {\n\t\tpanic(\"node has too many keys\")\n\t}\n}\n\nfunc (node *BTreeNode[T]) IsFull(maxKeys int) bool {\n\treturn node.numKeys == maxKeys\n}\n\nfunc (node *BTreeNode[T]) Search(key T) bool {\n\ti := 0\n\tfor ; i < node.numKeys; i++ {\n\t\tif key == node.keys[i] {\n\t\t\treturn true\n\t\t}\n\t\tif key < node.keys[i] {\n\t\t\tbreak\n\t\t}\n\t}\n\tif node.isLeaf {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/TheAlgorithms/Go/blob/5ba447ec5ff3d1213de65b92e726ee74c5d5cc19/structure/tree/btree.go#L32-L68","documentation":"Verify panics when a node holds more keys than the tree's maxKeys, exceeding the node's allocated capacity. Normally splits in Insert keep nodes within capacity, so this signals an out-of-band mutation or a node shared between trees with different maxKeys.","triggerScenarios":"Inserting into nodes without going through the tree's split logic (calling node-level helpers directly); moving a node from a tree with larger maxKeys into a tree with smaller maxKeys and calling Verify; writing past numKeys accounting with direct key appends.","commonSituations":"Copying nodes between BTree instances in tests or serialization code; custom batch-insert code that bypasses InsertNonFull's split path.","solutions":["Only insert keys through tree.Insert, which triggers Split when nodes fill.","Keep node ownership 1:1 with a single BTree and its maxKeys.","Rebuild the tree from scratch (re-insert all keys) if nodes were transferred between trees.","Run root.Verify after manual manipulations to catch corruption early."],"exampleFix":"// before\nleaf.Append(k, nil) // can exceed maxKeys\n// after\ntree.Insert(k) // splits full nodes automatically","handlingStrategy":"validation","validationCode":"if tree.root != nil {\n    tree.root.Verify(tree) // panics if any node overflows\n}\ntree.Insert(key)","typeGuard":null,"tryCatchPattern":"func safeInsert[T constraints.Ordered](t *BTree[T], k T) {\n    defer func() { _ = recover() }()\n    t.Insert(k)\n}","preventionTips":["Insert only via tree.Insert so splits run","Do not move nodes between trees","Use Append/Concat only inside library-internal code"],"tags":["panic","btree","invariant-violation"],"backgroundTag":"btree-invariant-violation","analyzedSha":"5ba447ec5ff3d1213de65b92e726ee74c5d5cc19","analyzedAt":"2026-09-02T21:54:30.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}