{"record":{"id":"eb6a9a1444034d73","repo":"ethereum/go-ethereum","slug":"not-supported","errorCode":null,"errorMessage":"not supported","messagePattern":"not supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ethdb/remotedb/remotedb.go","lineNumber":61,"sourceCode":"\tvar resp hexutil.Bytes\n\terr := db.remote.Call(&resp, \"debug_dbGet\", hexutil.Bytes(key))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp, nil\n}\n\nfunc (db *Database) Ancient(kind string, number uint64) ([]byte, error) {\n\tvar resp hexutil.Bytes\n\terr := db.remote.Call(&resp, \"debug_dbAncient\", kind, number)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp, nil\n}\n\nfunc (db *Database) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) {\n\tpanic(\"not supported\")\n}\n\nfunc (db *Database) Ancients() (uint64, error) {\n\tvar resp uint64\n\terr := db.remote.Call(&resp, \"debug_dbAncients\")\n\treturn resp, err\n}\n\nfunc (db *Database) Tail(group string) (uint64, error) {\n\tpanic(\"not supported\")\n}\n\nfunc (db *Database) AncientSize(kind string) (uint64, error) {\n\tpanic(\"not supported\")\n}\n\nfunc (db *Database) ReadAncients(fn func(op ethdb.AncientReaderOp) error) (err error) {\n\treturn fn(db)","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/ethereum/go-ethereum/blob/6bb0588ad8e7f922e4ad5580f51265a4097af08f/ethdb/remotedb/remotedb.go#L43-L79","documentation":"remotedb.Database is a read-only key-value view over a remote node's debug RPC namespace (debug_dbGet / debug_dbAncient). AncientRange bulk-reads from the freezer; because no equivalent streaming RPC exists, the method panics with 'not supported' instead of returning data or an error.","triggerScenarios":"Creating a db via remotedb.New(rpcClient) and calling AncientRange(kind, start, count, maxBytes) on it — typically from generic ethdb-consuming code such as chain iteration, snapshot tooling, or freezer readers.","commonSituations":"Diagnostics tools built on remotedb that are later handed to generic components expecting a full ethdb.AncientReader/AncientWriter; reusing analysis scripts against new code paths that bulk-read ancient data.","solutions":["Do not call AncientRange on a remotedb; use Ancient(kind, number) repeatedly via debug_dbAncient for individual records.","Run the tooling locally against the node's datadir (leveldb/freezer) if bulk ancient reads are required.","Expose a custom RPC on the remote node that streams the range, and call that instead."],"exampleFix":"// before\nitems, err := db.AncientRange(\"headers\", 0, 100, 1<<20) // panics\n\n// after\nfor i := uint64(0); i < 100; i++ {\n    item, err := db.Ancient(\"headers\", i)\n    if err != nil { break }\n    _ = item\n}","handlingStrategy":"validation","validationCode":"if _, remote := db.(*remotedb.Database); remote {\n    // no bulk ancient reads over RPC: fall back to per-item reads\n    for i := start; i < start+count; i++ {\n        item, err := db.Ancient(kind, i)\n        if err != nil { return nil, err }\n        items = append(items, item)\n    }\n    return items, nil\n}\nreturn db.AncientRange(kind, start, count, maxBytes)","typeGuard":"func isRemoteReadOnly(db ethdb.Database) bool {\n    _, ok := db.(*remotedb.Database)\n    return ok\n}","tryCatchPattern":"If a third-party path may call it: wrap with defer/recover, detect the 'not supported' panic string, and retry with per-item Ancient() reads.","preventionTips":["Know which ethdb methods the debug namespace backs: Has/Get/Ancient/Ancients only.","Type-assert remotedb before entering bulk ancient code.","Keep a local freezer handle for any tool needing AncientRange."],"tags":["remotedb","ancient-store","read-only","freezer","panic"],"backgroundTag":null,"analyzedSha":"6bb0588ad8e7f922e4ad5580f51265a4097af08f","analyzedAt":"2026-08-15T10:06:53.996Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}