{"record":{"id":"99bb3fd062905b37","repo":"ipfs/kubo","slug":"error-traversing-dag-w","errorCode":null,"errorMessage":"error traversing DAG: %w","messagePattern":"error traversing DAG: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/dag/stat.go","lineNumber":99,"sourceCode":"\t\t\t\t// unique total. With multiple roots, cidSet tracks which CIDs were\n\t\t\t\t// already counted under a previous root (Visit reports true the\n\t\t\t\t// first time a CID is seen).\n\t\t\t\tif cidSet == nil || cidSet.Visit(current.Node.Cid()) {\n\t\t\t\t\tdagStatSummary.incrementTotalSize(currentNodeSize)\n\t\t\t\t}\n\t\t\t\tdagStatSummary.incrementRedundantSize(currentNodeSize)\n\t\t\t\tif progressive {\n\t\t\t\t\tif err := res.Emit(dagStatSummary); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t\tErrFunc:        nil,\n\t\t\tSkipDuplicates: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error traversing DAG: %w\", err)\n\t\t}\n\t}\n\n\tif cidSet != nil {\n\t\tdagStatSummary.UniqueBlocks = cidSet.Len()\n\t} else {\n\t\t// Single root: boxo deduplicated within the traversal, so the number of\n\t\t// unique blocks equals the number of blocks visited.\n\t\tfor _, ds := range dagStatSummary.DagStatsArray {\n\t\t\tdagStatSummary.UniqueBlocks += int(ds.NumBlocks)\n\t\t}\n\t}\n\tdagStatSummary.calculateSummary()\n\n\tif err := res.Emit(dagStatSummary); err != nil {\n\t\treturn err\n\t}\n\treturn nil","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/dag/stat.go#L81-L117","documentation":"`ipfs dag stat` walks the DAG with an ipld-prime traverser to count blocks and sizes. If the traversal itself fails (missing blocks, decode errors, link errors), the command wraps the traversal error as `error traversing DAG: %w`.","triggerScenarios":"Missing blocks (offline node without the full DAG), undecodable nodes, or a bad link encountered during `ipfs dag stat`.","commonSituations":"Running dag stat offline/on a node without the data (`context deadline exceeded` or \"block not found\" wrapped inside); partial imports with --local-only followed by stat without --local; corrupted blocks.","solutions":["Ensure the node is online and the full DAG is fetchable, or import the complete CAR first","Read the wrapped inner error: block-not-found means fetch data; decode errors mean corrupt data","Use `ipfs dag stat --local` only when the full DAG is known present locally","Re-add/re-import from a verified source if blocks are corrupt"],"exampleFix":"// before\nipfs dag stat /ipfs/<cid>   # offline node, partial data\n// after\nipfs dag import full.car    # or start daemon\nipfs dag stat /ipfs/<cid>","handlingStrategy":"try-catch","validationCode":"// check local availability first when offline\nif offline {\n    if out, err := exec.Command(\"ipfs\", \"dag\", \"stat\", \"--local\", path).Output(); err != nil {\n        return fmt.Errorf(\"DAG incomplete locally: %s\", out)\n    }\n}","typeGuard":null,"tryCatchPattern":"// CLI: parse wrapped traversal cause\nif err := run(\"ipfs\", \"dag\", \"stat\", path); err != nil {\n    if strings.Contains(errText(err), \"not found\") {\n        // start daemon / fetch DAG, then retry\n        return retryAfterFetch(path)\n    }\n    return err\n}","preventionTips":["Run dag stat with a connected daemon unless using --local","Import the full CAR before statting offline","Check wrapped inner error to distinguish missing vs corrupt blocks"],"tags":["cli","dag-stat","traversal","missing-blocks"],"backgroundTag":"dag-traversal-failed","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}