GoogleContainerTools/skaffold · error
unable to list files:
Error message
unable to list files:
What it means
walk.builder.MustDo runs the file-tree walk action and panics with "unable to list files: <err>" if Do returns an error. It is a convenience for call sites where a failed dependency/file listing makes further progress impossible, converting fs errors (permission denied, missing directory, symlink loops) into a panic.
Source
Thrown at pkg/skaffold/walk/walk.go:155
return action(w.dir, info)
}
return godirwalk.Walk(w.dir, &godirwalk.Options{
Unsorted: w.unsorted,
Callback: func(path string, info *godirwalk.Dirent) error {
match, err := w.predicate(path, info)
if !match || err != nil {
return err
}
return action(path, info)
},
})
}
func (w *builder) MustDo(action Action) {
if err := w.Do(action); err != nil {
panic("unable to list files: " + err.Error())
}
}
// Predicates
func hasName(name string) Predicate {
return func(_ string, info Dirent) (bool, error) {
return info.Name() == name, nil
}
}
func nameMatches(glob string) Predicate {
return func(_ string, info Dirent) (bool, error) {
return path.Match(glob, info.Name())
}
}
func isDir(_ string, info Dirent) (bool, error) {View on GitHub (pinned to a1189de023)
Solutions
- Fix filesystem permissions on the unreadable directory shown in the wrapped error
- Raise the open-file limit (ulimit -n) for large trees hitting EMFILE
- Remove or fix broken/cyclic symlinks in the workspace
- Use the non-panicking Do API and handle the error at the call site if a partial walk is acceptable
Example fix
// before
walker.MustDo(func(path string, _ fs.FileInfo) error { ... })
// after
err := walker.Do(func(path string, _ fs.FileInfo) error { ... })
if err != nil {
return fmt.Errorf("listing files: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(workspaceRoot); err != nil {
return fmt.Errorf("workspace inaccessible: %w", err)
}
if fi, err := os.Stat(workspaceRoot); err == nil && !fi.IsDir() {
return fmt.Errorf("workspace is not a directory")
} Type guard
func dirReadable(path string) bool {
f, err := os.Open(path)
if err != nil { return false }
f.Close()
return true
} Try / catch
func walkSafe(b *walk.Builder, a walk.Action) (err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("walk failed: %v", r) } }()
b.MustDo(a)
return nil
} Prevention
- Run skaffold with read access to the entire workspace (avoid root-owned build dirs)
- Raise ulimit -n on large repos
- Prune broken symlinks and exclude node_modules/build output from walks
- Prefer Do() over MustDo() in code that can tolerate a failed listing
When it happens
Trigger: Calling MustDo (e.g. while building the dependency list for watching/diagnose) when walking the workspace fails: unreadable directory (permissions), deleted directory mid-walk, too many open files, or symlink cycles.
Common situations: Build artifacts or node_modules owned by root/unreadable by the skaffold process; workspace path deleted while skaffold runs; ENFILE/EMFILE file-descriptor limits on large monorepos; broken symlinks in the source tree.
Related errors
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/5aa4564b27e54e0c.
Report an issue: GitHub.