GoogleContainerTools/skaffold · error

changed file %s can't be found relative to context %q: %w

Error message

changed file %s can't be found relative to context %q: %w

What it means

intersect maps each changed file into destination paths by first computing its path relative to the build context (contextWd). If filepath.Rel(contextWd, file) fails, the file cannot be related to the sync rules' source-relative paths, so Skaffold wraps the error.

Source

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

		return nil, fmt.Errorf("Sync: Auto is not supported by the build of %s", a.ImageName)
	}
}

func latestTag(image string, builds []graph.Artifact) string {
	for _, build := range builds {
		if build.ImageName == image {
			return build.Tag
		}
	}
	return ""
}

func intersect(ctx context.Context, contextWd, containerWd string, syncRules []*latest.SyncRule, files []string) (syncMap, error) {
	ret := make(syncMap)
	for _, f := range files {
		relPath, err := filepath.Rel(contextWd, f)
		if err != nil {
			return nil, fmt.Errorf("changed file %s can't be found relative to context %q: %w", f, contextWd, err)
		}

		dsts, err := matchSyncRules(syncRules, relPath, containerWd)
		if err != nil {
			return nil, err
		}

		if len(dsts) == 0 {
			log.Entry(ctx).Infof("Changed file %s does not match any sync pattern. Skipping sync", relPath)
			return nil, nil
		}

		ret[f] = dsts
	}
	return ret, nil
}

func matchSyncRules(syncRules []*latest.SyncRule, relPath, containerWd string) ([]string, error) {

View on GitHub (pinned to a1189de023)

Solutions

  1. Ensure the workspace in skaffold.yaml is an absolute, symlink-resolved path that contains all watched files
  2. Normalize event file paths (filepath.Clean / EvalSymlinks) before calling syncItem
  3. Check that the jib/docker sync diff is generated against the same workspace root configured in skaffold.yaml

Example fix

// before
workspace: ~/project/app   # tilde not expanded, mismatch with events
// after
workspace: /home/dev/project/app
Defensive patterns

Strategy: validation

Validate before calling

for _, f := range files {
    if _, err := filepath.Rel(contextWd, f); err != nil {
        return fmt.Errorf("event file %s not under context %s", f, contextWd)
    }
}

Type guard

func underContext(contextWd, f string) bool {
    rel, err := filepath.Rel(contextWd, f)
    return err == nil && rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator))
}

Try / catch

_, err := sync.Sync(ctx, out, names, item)
if err != nil {
    if strings.Contains(err.Error(), "can't be found relative to context") {
        log.Warnf("dropping out-of-context file from sync: %v", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: A file event path lies outside (or is differently rooted than) the artifact workspace passed as contextWd — e.g. jib/docker sync diff producing absolute container-style paths, symlinked or differently cased workspace roots.

Common situations: Jib incremental sync returning paths from the Jib build cache that don't share a prefix with the workspace; watcher started at repo root while artifact workspace is a subdirectory and events escape it; Windows drive-letter casing mismatch.

Related errors


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