GoogleContainerTools/skaffold · error
filepath walk: %w
Error message
filepath walk: %w
What it means
After globbing, ExpandPathsGlob walks each matched path with walk.From(f).WhenIsFile().Do(...) to collect real files; this error wraps a failure from that walk. The walk fails when traversing a matched path hits an unreadable directory, a broken symlink being resolved, or the file disappears between globbing and walking. It aggregates the underlying walk error from dependency/test-path expansion.
Source
Thrown at pkg/skaffold/util/util.go:106
// This is a file reference, so just add it
set.Add(path)
continue
}
files, err := filepath.Glob(path)
if err != nil {
return nil, fmt.Errorf("glob: %w", err)
}
if len(files) == 0 {
log.Entry(context.TODO()).Warnf("%s did not match any file", p)
}
for _, f := range files {
if err := walk.From(f).WhenIsFile().Do(func(path string, _ walk.Dirent) error {
set.Add(path)
return nil
}); err != nil {
return nil, fmt.Errorf("filepath walk: %w", err)
}
}
}
return set.Files(), nil
}
func Ptr[T any](t T) *T {
o := t
return &o
}
func IsURL(s string) bool {
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}
// VerifyOrCreateFile checks if a file exists at the given path,
// and if not, creates all parent directories and creates the file.View on GitHub (pinned to a1189de023)
Solutions
- Check and fix read/execute permissions on every directory matched by the glob pattern.
- Remove or repair broken symlinks among the matched paths (find . -xtype l).
- Re-run — if a concurrent process deletes files mid-walk, make the dependency set stable before running Skaffold.
- Narrow the glob pattern so it only matches files that actually exist and are accessible.
Example fix
// before structureTests: ["tests/**/*"] # matches broken symlink tests/latest -> /nonexistent // after ln -sf /opt/tests/latest.json tests/latest.json # repair the symlink tests/latest.json
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check every glob match is a readable file
for _, f := range files {
info, err := os.Stat(f)
if err != nil || info.IsDir() {
return fmt.Errorf("dependency %q not a readable file", f)
}
if fi, _ := os.Lstat(f); fi.Mode()&os.ModeSymlink != 0 {
if _, err := os.Stat(f); err != nil {
return fmt.Errorf("broken symlink %q", f)
}
}
} Try / catch
deps, err := util.ExpandPathsGlob(fs, paths)
if err != nil {
if strings.Contains(err.Error(), "filepath walk:") {
log.Entry(ctx).Warnf("walk failed (%v); cleaning symlinks and retrying", err)
exec.Command("find", ".", "-xtype", "l", "-delete").Run()
deps, err = util.ExpandPathsGlob(fs, paths)
}
if err != nil { return err }
} Prevention
- Audit repos for broken symlinks (find . -xtype l) before builds.
- Ensure all dependency directories have read+execute for the running user.
- Keep the file tree stable while Skaffold resolves dependencies (no concurrent prune).
- On network volumes, avoid stale handles by remounting before long CI runs.
When it happens
Trigger: A glob match points to a directory the process cannot read (permission denied), a file matched by the glob is deleted between the Glob call and the walk, or a symlink target loop/missing target is encountered while expanding test or manifest dependencies.
Common situations: CI checkouts where files are pruned concurrently; NFS/overlay volumes with stale directory handles; restricted read permissions on dependency directories after a chown change; broken symlinks committed into the repo (e.g. symlink to a mounted toolchain path).
Related errors
- unable to list files:
- writing %q to %q: %w
- walking %q: %w
- reading .dockerignore: %w
- walking workspace: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/e4de2237ea3cfeb3.
Report an issue: GitHub.