{"record":{"id":"754cbb2d35a38714","repo":"ipfs/kubo","slug":"cannot-return-size-for-anything-other-than-a-dag-w","errorCode":null,"errorMessage":"cannot return size for anything other than a DAG with a root CID","messagePattern":"cannot return size for anything other than a DAG with a root CID","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/dag/stat.go","lineNumber":63,"sourceCode":"\t// just on remembering which CIDs were seen. On very large DAGs that second\n\t// copy has OOM-killed daemons running `dag stat` over multi-hundred-GiB\n\t// UnixFS roots, so allocate it only when there is more than one root.\n\tvar cidSet *cid.Set\n\tif len(req.Arguments) > 1 {\n\t\tcidSet = cid.NewSet()\n\t}\n\tdagStatSummary := &DagStatSummary{DagStatsArray: []*DagStat{}}\n\tfor _, a := range req.Arguments {\n\t\tp, err := cmdutils.PathOrCidPath(a)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trp, remainder, err := api.ResolvePath(req.Context, p)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(remainder) > 0 {\n\t\t\treturn fmt.Errorf(\"cannot return size for anything other than a DAG with a root CID\")\n\t\t}\n\n\t\tobj, err := nodeGetter.Get(req.Context, rp.RootCid())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdagstats := &DagStat{Cid: enc.Encode(rp.RootCid())}\n\t\tdagStatSummary.appendStats(dagstats)\n\t\terr = traverse.Traverse(obj, traverse.Options{\n\t\t\tDAG:   nodeGetter,\n\t\t\tOrder: traverse.DFSPre,\n\t\t\tFunc: func(current traverse.State) error {\n\t\t\t\tcurrentNodeSize := uint64(len(current.Node.RawData()))\n\t\t\t\tdagstats.Size += currentNodeSize\n\t\t\t\tdagstats.NumBlocks++\n\t\t\t\t// With a single root, boxo's SkipDuplicates guarantees each CID is\n\t\t\t\t// visited exactly once, so every block counts toward the global\n\t\t\t\t// unique total. With multiple roots, cidSet tracks which CIDs were","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/dag/stat.go#L45-L81","documentation":"`ipfs dag stat` computes size/counts for a whole DAG identified by a root CID. If the requested path resolves with a remaining path segment (e.g. /ipfs/<cid>/a/b), there is no single root DAG to measure, so the command refuses with this error.","triggerScenarios":"`ipfs dag stat /ipfs/<cid>/sub/path` — any path with components after the CID.","commonSituations":"Pasting a gateway-style deep path into dag stat; scripting that appends UnixFS path segments; intending `ipfs files stat` or `ipfs object stat` instead.","solutions":["Use only the root: `ipfs dag stat /ipfs/<cid>`","Resolve the subpath to a CID first (e.g. `ipfs resolve /ipfs/<cid>/sub`) and stat that CID","Use `ipfs files stat` or `ipfs ls` for path-based traversal info"],"exampleFix":"// before\nipfs dag stat /ipfs/bafy.../photos/img.png\n// after\nipfs resolve /ipfs/bafy.../photos/img.png\n# then\nipfs dag stat <resolved-cid>","handlingStrategy":"validation","validationCode":"// strip path remainder to a root CID before dag stat\np := strings.TrimPrefix(pathStr, \"/ipfs/\")\nroot, rest, _ := strings.Cut(p, \"/\")\nif rest != \"\" {\n    out, _ := exec.Command(\"ipfs\", \"resolve\", pathStr).Output()\n    pathStr = strings.TrimSpace(string(out)) // now a bare CID path\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass only root CID paths to dag stat","Resolve subpaths to CIDs first when needed","Use files stat / ls for deep path inspection"],"tags":["cli","dag-stat","path-resolution"],"backgroundTag":"dag-path-has-remainder","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"}