GoogleContainerTools/skaffold · error
deleting files: %w
Error message
deleting files: %w
What it means
`ContainerSyncer.Sync` wraps failures from running the delete command (`s.deleteFileFn`) used to remove deleted files from inside the running container during file sync. The sync of file deletions to the container failed, so the incremental sync did not fully apply.
Source
Thrown at pkg/skaffold/sync/docker.go:46
type ContainerSyncer struct{}
func NewContainerSyncer() *ContainerSyncer {
return &ContainerSyncer{}
}
func (s *ContainerSyncer) Sync(ctx context.Context, _ io.Writer, item *Item) error {
if len(item.Copy) > 0 {
log.Entry(ctx).Info("Copying files:", item.Copy, "to", item.Image)
if _, err := util.RunCmdOut(ctx, s.copyFileFn(ctx, item.Artifact.ImageName, item.Copy)); err != nil {
return fmt.Errorf("copying files: %w", err)
}
}
if len(item.Delete) > 0 {
log.Entry(ctx).Info("Deleting files:", item.Delete, "from", item.Image)
if _, err := util.RunCmdOut(ctx, s.deleteFileFn(ctx, item.Artifact.ImageName, item.Delete)); err != nil {
return fmt.Errorf("deleting files: %w", err)
}
}
return nil
}
func (s *ContainerSyncer) deleteFileFn(ctx context.Context, containerName string, files syncMap) *exec.Cmd {
var args []string
args = append(args, "exec", "-i", containerName, "rm", "-rf", "--")
for _, dsts := range files {
args = append(args, dsts...)
}
return exec.CommandContext(ctx, "docker", args...)
}
func (s *ContainerSyncer) copyFileFn(ctx context.Context, containerName string, files syncMap) *exec.Cmd {
reader, writer := io.Pipe()
go func() {View on GitHub (pinned to a1189de023)
Solutions
- Verify the container is running and the image name matches the running container.
- Check the container filesystem is writable (not readOnlyRootFilesystem) and the container user can delete the paths.
- Trigger a full rebuild/redeploy instead of file sync if the deleted file is baked into the image and critical.
- Ensure docker/kubectl CLI is installed and the daemon/cluster is reachable.
Example fix
// before securityContext: readOnlyRootFilesystem: true // rm inside container fails // after securityContext: readOnlyRootFilesystem: false // or mount an emptyDir at the affected path
Defensive patterns
Strategy: try-catch
Validate before calling
rw, _, err := exec.Command("docker", "inspect", "-f", "{{.HostConfig.ReadonlyRootfs}}", imageName).Output()
if err == nil && strings.TrimSpace(string(rw)) == "true" {
return fmt.Errorf("container rootfs is read-only; delete sync will fail")
} Try / catch
err := syncer.Sync(ctx, out, item)
if err != nil {
if strings.Contains(err.Error(), "deleting files") {
log.Printf("delete sync failed (%v); falling back to rebuild", err)
return triggerRebuild(item.Artifact)
}
return err
} Prevention
- Avoid readOnlyRootFilesystem on containers you hot-sync deletions into, or mount a writable volume at those paths.
- Ensure the container's user has write permission on synced directories.
- Confirm the container wasn't restarted/exited before the sync fires.
- Use manual sync rules scoped to writable paths only.
When it happens
Trigger: Calling `Sync` with a non-empty `Delete` list while the container is not running, the image/container reference is invalid, the underlying CLI (`docker exec rm`, etc.) fails due to permissions or a read-only filesystem inside the container.
Common situations: Deleting a file locally while the container has a read-only root filesystem (readOnlyRootFilesystem securityContext); container restarted between build and sync; container user lacks permission to remove the path; docker daemon unavailable.
Related errors
- copying files: %w
- retrieving working dir for %q: %w
- inferring syncmap for image %q: %w
- walking workspace: %w
- could not find latest tag for image %s in builds: %v
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/276a9ce96fc34409.
Report an issue: GitHub.