GoogleContainerTools/skaffold · error

walking %q: %w

Error message

walking %q: %w

What it means

When a sync source is a directory, walkWorkspaceWithDestinations walks it with a keep-file filter to build destination mappings. If the underlying walk fails (unreadable directory, symlink loop, walk callback error), the error is wrapped as 'walking %q' with the absolute source path.

Source

Thrown at pkg/skaffold/docker/syncmap.go:108

				return !ignored, nil
			}

			if err := walk.From(absFrom).Unsorted().When(keepFile).WhenIsFile().Do(func(fpath string, info walk.Dirent) error {
				relPath, err := filepath.Rel(workspace, fpath)
				if err != nil {
					return err
				}

				relBase, err := filepath.Rel(absFrom, fpath)
				if err != nil {
					return err
				}

				srcByDest[path.Join(ft.To, filepath.ToSlash(relBase))] = relPath
				return nil
			}); err != nil {
				return nil, fmt.Errorf("walking %q: %w", absFrom, err)
			}
		case mode.IsRegular():
			ignored, err := dockerIgnored(filepath.Join(workspace, ft.From), fi)
			if err != nil {
				return nil, err
			}

			if !ignored {
				if ft.ToIsDir {
					base := filepath.Base(ft.From)
					srcByDest[path.Join(ft.To, base)] = ft.From
				} else {
					srcByDest[ft.To] = ft.From
				}
			}
		}
	}

View on GitHub (pinned to a1189de023)

Solutions

  1. Check permissions on the sync directory and all subdirectories (find <dir> -type d ! -perm -o+x)
  2. Inspect nested symlinks inside the directory (find <dir> -type l -exec test ! -e {} \;) and remove broken ones
  3. Raise the open file limit (ulimit -n) if 'too many open files' appears in the wrapped error
  4. Read the wrapped inner error to identify whether the failure is I/O or a dockerignore parsing issue
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(filepath.Join(workspace, ft.From))
if err == nil && info.IsDir() {
    if err := filepath.WalkDir(filepath.Join(workspace, ft.From), func(p string, d fs.DirEntry, err error) error {
        return err
    }); err != nil {
        return fmt.Errorf("sync dir %q unreadable: %w", ft.From, err)
    }
}

Type guard

func walkableDir(path string) bool {
    fi, err := os.Stat(path)
    return err == nil && fi.IsDir()
}

Try / catch

if err := SyncMap(fts, workspace); err != nil {
    if strings.Contains(err.Error(), "walking") && errors.Is(err, fs.ErrPermission) {
        log.Warnf("skipping unreadable sync directory: %v", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: os.Stat succeeded (path is a directory) but the walk cannot traverse it: permission denied on subdirectories, too many open files, or the keepFile callback (including dockerIgnored evaluation) returns an error.

Common situations: Directory readable at top level but subdirectories lack +x permission; broken symlinks inside the sync dir; extremely large directories hitting ulimit; git worktrees or mounted volumes with restricted permissions in containers/CI.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/a0801a5856115548. Report an issue: GitHub.