{"record":{"id":"254cbe0ace831074","repo":"ethereum/go-ethereum","slug":"not-at-leaf","errorCode":null,"errorMessage":"not at leaf","messagePattern":"not at leaf","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"trie/iterator.go","lineNumber":222,"sourceCode":"\nfunc (it *nodeIterator) Parent() common.Hash {\n\tif len(it.stack) == 0 {\n\t\treturn common.Hash{}\n\t}\n\treturn it.stack[len(it.stack)-1].parent\n}\n\nfunc (it *nodeIterator) Leaf() bool {\n\treturn hasTerm(it.path)\n}\n\nfunc (it *nodeIterator) LeafKey() []byte {\n\tif len(it.stack) > 0 {\n\t\tif _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok {\n\t\t\treturn hexToKeybytes(it.path)\n\t\t}\n\t}\n\tpanic(\"not at leaf\")\n}\n\nfunc (it *nodeIterator) LeafBlob() []byte {\n\tif len(it.stack) > 0 {\n\t\tif node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok {\n\t\t\treturn node\n\t\t}\n\t}\n\tpanic(\"not at leaf\")\n}\n\nfunc (it *nodeIterator) LeafProof() [][]byte {\n\tif len(it.stack) > 0 {\n\t\tif _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok {\n\t\t\thasher := newHasher(false)\n\t\t\tdefer returnHasherToPool(hasher)\n\t\t\tproofs := make([][]byte, 0, len(it.stack))\n","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/ethereum/go-ethereum/blob/6bb0588ad8e7f922e4ad5580f51265a4097af08f/trie/iterator.go#L204-L240","documentation":"nodeIterator.LeafKey panics when the iterator is not positioned at a value leaf. LeafKey is only meaningful after Next() has landed on a leaf node (path terminated by hex 16 and stack top is a valueNode); calling it on an internal node or before the first Next is a misuse of the iterator API.","triggerScenarios":"Calling it.LeafKey() before checking it.Leaf(); calling it after Next() returned an internal (non-leaf) node; calling it after the iterator was exhausted.","commonSituations":"Iterating a trie and assuming every step yields a key; porting loops that used EthDatabase iteration semantics; forgetting the Next()-then-check-Leaf() contract of trie.NodeIterator.","solutions":["Guard with if it.Leaf() { key := it.LeafKey() ... } before calling LeafKey.","Always advance with Next(true/false) first and stop when it returns false.","Read LeafKey/LeafBlob/LeafProof only within the same iteration step that reported Leaf()==true."],"exampleFix":"// before\nfor it.Next(true) {\n    key := it.LeafKey() // panics on non-leaf steps\n}\n\n// after\nfor it.Next(true) {\n    if it.Leaf() {\n        key := it.LeafKey()\n        _ = key\n    }\n}","handlingStrategy":"validation","validationCode":"for it.Next(true) {\n    if !it.Leaf() {\n        continue // structural node, LeafKey invalid here\n    }\n    key := it.LeafKey()\n    _ = key\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always branch on it.Leaf() before LeafKey/LeafBlob/LeafProof.","Never call leaf accessors before the first Next() or after Next() returns false.","Wrap iteration in helper functions that enforce the leaf guard once."],"tags":["trie","iterator","api-misuse","leaf","panic","go"],"backgroundTag":null,"analyzedSha":"6bb0588ad8e7f922e4ad5580f51265a4097af08f","analyzedAt":"2026-08-15T10:06:53.996Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}