{"record":{"id":"2fadd848ace71d7e","repo":"ipfs/kubo","slug":"error-listing-directory-w","errorCode":null,"errorMessage":"error listing directory: %w","messagePattern":"error listing directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/coreiface/unixfs.go","lineNumber":112,"sourceCode":"\t//\tfor dirEnt := range dirs {\n\t//\t\tfmt.Println(\"Dir name:\", dirEnt.Name)\n\t//\t}\n\t//\terr := <-lsErr\n\t//\tif err != nil {\n\t//\t\treturn fmt.Errorf(\"error listing directory: %w\", err)\n\t//\t}\n\tLs(context.Context, path.Path, chan<- DirEntry, ...options.UnixfsLsOption) error\n}\n\n// LsIter returns a go iterator that allows ranging over DirEntry results.\n// Iteration stops if the context is canceled or if the iterator yields an\n// error.\n//\n// Example:\n//\n//\tfor dirEnt, err := LsIter(ctx, ufsAPI, p) {\n//\t\tif err != nil {\n//\t\t\treturn fmt.Errorf(\"error listing directory: %w\", err)\n//\t\t}\n//\t\tfmt.Println(\"Dir name:\", dirEnt.Name)\n//\t}\nfunc LsIter(ctx context.Context, api UnixfsAPI, p path.Path, opts ...options.UnixfsLsOption) iter.Seq2[DirEntry, error] {\n\treturn func(yield func(DirEntry, error) bool) {\n\t\tctx, cancel := context.WithCancel(ctx)\n\t\tdefer cancel() // cancel Ls if done iterating early\n\n\t\tdirs := make(chan DirEntry)\n\t\tlsErr := make(chan error, 1)\n\t\tgo func() {\n\t\t\tlsErr <- api.Ls(ctx, p, dirs, opts...)\n\t\t}()\n\t\tfor dirEnt := range dirs {\n\t\t\tif !yield(dirEnt, nil) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/coreiface/unixfs.go#L94-L130","documentation":"LsIter is a pull-style iterator over UnixFS directory entries. Because iter.Seq2 cannot return a single error, failures (path resolution errors, node fetch errors, blockservice errors) are surfaced as the second yield value; this message is the documented pattern for wrapping them so the 'error listing directory' context is preserved. The library itself just forwards the underlying error from the directory listing operation.","triggerScenarios":"Calling LsIter (or Ls) on coreapi.UnixfsAPI with a path that does not exist, is not a UnixFS directory (e.g. a regular file), points to a CID whose blocks cannot be fetched from the network, or continuing to iterate after the context was cancelled.","commonSituations":"Typo in an IPFS path (/ipfs/<cid>/subdir that doesn't exist); listing a sharded/huge directory offline where peers are unreachable; passing a path to a file instead of a directory; using a context cancelled mid-iteration.","solutions":["Check the wrapped underlying error (%w) to identify the true cause (not found vs fetch failure vs not-a-directory)","Verify the path resolves to a directory: use ufs.Stat or ipfs files stat before listing","Ensure the daemon is online and the content is available locally or on the network (ipfs refs local, ipfs dht findprovs)","Handle errors inside the iteration loop exactly as the doc comment shows, wrapping with %w and returning"],"exampleFix":"// before\nfor dirEnt, err := ufs.LsIter(ctx, api, p) {\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error listing directory: %w\", err)\n\t}\n\t_ = dirEnt\n}\n// after\nstat, serr := ufs.Stat(ctx, p)\nif serr != nil {\n\treturn fmt.Errorf(\"path not found: %w\", serr)\n}\nif stat.Type != FileTypeDirectory {\n\treturn fmt.Errorf(\"%s is not a directory\", p)\n}\nfor dirEnt, err := ufs.LsIter(ctx, api, p) {\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error listing directory: %w\", err)\n\t}\n\tprocess(dirEnt)\n}","handlingStrategy":"try-catch","validationCode":"stat, err := ufs.Stat(ctx, p)\nif err != nil { return err }\nif stat.Type != FileTypeDirectory { return fmt.Errorf(\"%s is not a directory\", p) }","typeGuard":"func isDirEntryStat(s *coreiface.Stat) bool { return s != nil && s.Type == coreiface.FileTypeDirectory }","tryCatchPattern":"for ent, err := range coreiface.LsIter(ctx, api, p) {\n\tif err != nil {\n\t\tvar nfe *NotFoundError\n\t\tif errors.As(err, &nfe) { continue } // skip vanished entries\n\t\treturn fmt.Errorf(\"error listing directory: %w\", err)\n\t}\n\tprocess(ent)\n}","preventionTips":["Always range LsIter with an error check inside the loop body, per the doc comment","Stat the path and confirm it is a directory before listing","Use a context with a timeout so hung fetches fail instead of blocking","Keep the daemon connected/online when listing non-local content"],"tags":["unixfs","directory-listing","error-wrapping","iterator"],"backgroundTag":"directory-list-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"}