GoogleContainerTools/skaffold · error

intersecting sync map and deleted files

Error message

intersecting sync map and deleted files: %w

What it means

`syncItem` wraps failures from `intersect` when computing deletions: deleted workspace files must be matched against sync rules to know which container paths to remove. Failure here means the delete-side sync map could not be computed, so the sync Item is aborted (the caller rebuilds instead of syncing).

Solutions

  1. Verify deleted paths were inside the artifact workspace and the workspace config hasn't changed.
  2. Restart `skaffold dev` to reset watcher/sync state after branch switches or bulk deletions.
  3. Force a full rebuild (touch a source file or use --force) so stale delete events are discarded.
  4. Check sync rules (manual/infer) in skaffold.yaml match the file locations being deleted.

Example fix

// before
git checkout other-branch // mass delete confuses sync
// after
# stop dev, switch branch, restart
skaffold dev
Defensive patterns

Strategy: fallback

Validate before calling

wd, _ := filepath.Abs(artifact.Workspace)
for _, f := range events.Deleted {
  abs, _ := filepath.Abs(f)
  if rel, err := filepath.Rel(wd, abs); err != nil || strings.HasPrefix(rel, "..") {
    return triggerRebuild(artifact) // deletions outside workspace: rebuild instead
  }
}

Try / catch

if err := runSync(...); err != nil {
  if strings.Contains(err.Error(), "intersecting sync map and deleted files") {
    log.Printf("delete sync failed (%v); falling back to rebuild", err)
    return triggerRebuild(artifact)
  }
  return err
}

Prevention

When it happens

Trigger: Calling `syncItem` with `e.Deleted` entries whose paths cannot be relativized against `a.Workspace` or matched to sync rules — e.g. the file was already removed so rel/exists checks fail, or paths point outside the workspace.

Common situations: Deleting files via git operations (checkout/branch switch) that batch-delete paths the watcher reports oddly; deleting symlinked or generated files; workspace path changed between builds so old paths no longer relativize; case-sensitive vs case-insensitive filesystem mismatches.

Related errors


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

Appendix: source

Thrown at pkg/skaffold/sync/sync.go:98

	default:
		return nil, nil
	}
}

func syncItem(ctx context.Context, a *latest.Artifact, tag string, e filemon.Events, syncRules []*latest.SyncRule, cfg docker.Config) (*Item, error) {
	containerWd, err := WorkingDir(ctx, tag, cfg)
	if err != nil {
		return nil, fmt.Errorf("retrieving working dir for %q: %w", tag, err)
	}

	toCopy, err := intersect(ctx, a.Workspace, containerWd, syncRules, append(e.Added, e.Modified...))
	if err != nil {
		return nil, fmt.Errorf("intersecting sync map and added, modified files: %w", err)
	}

	toDelete, err := intersect(ctx, a.Workspace, containerWd, syncRules, e.Deleted)
	if err != nil {
		return nil, fmt.Errorf("intersecting sync map and deleted files: %w", err)
	}

	// Something went wrong, don't sync, rebuild.
	if toCopy == nil || toDelete == nil {
		return nil, nil
	}

	return &Item{Image: tag, Artifact: a, Copy: toCopy, Delete: toDelete}, nil
}

func inferredSyncItem(ctx context.Context, a *latest.Artifact, tag string, e filemon.Events, cfg docker.Config) (*Item, error) {
	// the ko builder doesn't need or use a sync map
	if a.KoArtifact != nil {
		log.Entry(ctx).Debugf("ko inferred sync %+v", e)
		toCopy, toDelete, err := kosync.Infer(ctx, a, e)
		if err != nil {
			return nil, err
		}

View on GitHub (pinned to a1189de023)