TheAlgorithms/Go · error
Called InsertNonFull() with a full node
Error message
Called InsertNonFull() with a full node
What it means
InsertNonFull must only be called on a node that is not full; the method checks IsFull first and panics if the node already holds maxKeys. It is an internal invariant — callers (the tree itself) are responsible for splitting full children before recursing.
Source
Thrown at structure/tree/btree.go:152
// Reuse child as the left node
child.numKeys = midKeyIndex
// Insert the child's mid index to the parent
for i := parent.numKeys; i > idx; i-- {
parent.keys[i] = parent.keys[i-1]
parent.children[i+1] = parent.children[i]
}
parent.keys[idx] = child.keys[midKeyIndex]
parent.children[idx] = child
parent.children[idx+1] = rightChild
parent.numKeys += 1
}
func (node *BTreeNode[T]) InsertNonFull(tree *BTree[T], key T) {
node.Verify(tree)
if node.IsFull(tree.maxKeys) {
panic("Called InsertNonFull() with a full node")
}
if node.isLeaf {
// Node is a leaf. Directly insert the key.
node.InsertKeyChild(key, nil)
return
}
// Find the child node to insert into
i := 0
for ; i < node.numKeys; i++ {
if key < node.keys[i] {
break
}
}
if node.children[i].IsFull(tree.maxKeys) {
node.Split(i, tree.maxKeys)View on GitHub (pinned to 5ba447ec5f)
Solutions
- Call tree.Insert(key) instead of node.InsertNonFull directly — it handles root splitting.
- If calling InsertNonFull on a child, check node.IsFull(tree.maxKeys) and call Split first.
- Add a wrapper in your code that splits the root when full before recursing.
Example fix
// before
if tree.root.IsFull(tree.maxKeys) { /* forgot split */ }
tree.root.InsertNonFull(tree, key)
// after
tree.Insert(key) Defensive patterns
Strategy: try-catch
Validate before calling
if tree.root != nil && tree.root.IsFull(tree.maxKeys) {
// split root first or just use tree.Insert
}
tree.Insert(key) Try / catch
func safeInsertNonFull[T constraints.Ordered](n *BTreeNode[T], t *BTree[T], k T) (err error) {
defer func() {
if r := recover(); r != nil { err = fmt.Errorf("insert failed: %v", r) }
}()
if n.IsFull(t.maxKeys) { return errors.New("node full; split first") }
n.InsertNonFull(t, k)
return nil
} Prevention
- Prefer tree.Insert over node-level APIs
- Split before recursing into full children
- Keep custom rebalancing minimal and tested
When it happens
Trigger: Calling node.InsertNonFull(tree, key) directly on a node with numKeys == maxKeys without splitting first; misuse of the exported node-level API on the root when the tree should have split the root first.
Common situations: Custom insert loops in application code that call node methods instead of tree.Insert; tests reaching into internals; a new root created without the split being performed.
Related errors
- BTree maxKeys cannot be zero
- Must be >= 3 keys
- node has too few keys
- node has too many keys
- deleting out of bounds key
AI-assisted analysis of TheAlgorithms/Go@5ba447ec5f (2026-09-02).
Data as JSON: /api/errors/62681a887dc33fc6.
Report an issue: GitHub.