kubernetes/kops · error
different types for copy target %s
Error message
different types for copy target %s
What it means
Copy deduplicates file copy tasks by name (the target file path). If a task name already exists in the map but holds a *CopyImage instead of a *CopyFile (or vice versa), the target is being used for two different task kinds, so Copy aborts with this error.
Source
Thrown at pkg/assets/assetcopy/copy.go:72
tasks[copyImageTask.Name] = copyImageTask
}
}
for _, fileAsset := range fileAssets {
if fileAsset.DownloadURL.String() != fileAsset.CanonicalURL.String() {
copyFileTask := &CopyFile{
Name: fileAsset.CanonicalURL.String(),
TargetFile: fileAsset.DownloadURL.String(),
SourceFile: fileAsset.CanonicalURL.String(),
SHA: fileAsset.SHAValue.Hex(),
VFSContext: vfsContext,
Cluster: cluster,
}
if existing, ok := tasks[copyFileTask.Name]; ok {
e, ok := existing.(*CopyFile)
if !ok {
return fmt.Errorf("different types for copy target %s", copyFileTask.Name)
}
if e.TargetFile != copyFileTask.TargetFile {
return fmt.Errorf("different targets for same file %s: %s vs %s", copyFileTask.Name, copyFileTask.TargetFile, e.TargetFile)
}
if e.SHA != copyFileTask.SHA {
return fmt.Errorf("different sha for same file %s: %s vs %s", copyFileTask.Name, copyFileTask.SHA, e.SHA)
}
}
tasks[copyFileTask.Name] = copyFileTask
}
}
ch := make(chan error, 5)
for i := 0; i < cap(ch); i++ {
ch <- nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Make file and image targets occupy distinct namespaces/names so they never collide
- Fix the asset configuration that reuses one target name for both a file path and an image target
- Regenerate the asset list so each target is produced by exactly one task type
Defensive patterns
Strategy: validation
Validate before calling
names := map[string]string{}
for _, t := range allTasks {
if prev, ok := names[t.Name()]; ok && prev != fmt.Sprintf("%T", t) {
return fmt.Errorf("pre-check: target %s reused by %s and %s", t.Name(), prev, fmt.Sprintf("%T", t))
}
names[t.Name()] = fmt.Sprintf("%T", t)
} Type guard
func targetIsFreeForFile(tasks map[string]Task, name string) bool {
_, occupied := tasks[name]
return !occupied
} Try / catch
if err := copy.Run(ctx); err != nil {
if strings.Contains(err.Error(), "different types for copy target") {
return fmt.Errorf("asset config bug: %w — file and image targets must not share a name", err)
}
return err
} Prevention
- Keep image targets and file paths in disjoint name spaces
- Review generated asset names for collisions between asset kinds
- Avoid reusing one target string for both image tags and file destinations
When it happens
Trigger: A file asset's target path equals an image asset's target name within one Copy run, so tasks[name] holds a *CopyImage when a *CopyFile is inserted (or the map contains a non-CopyFile value under that name).
Common situations: Misconfigured asset targets where a file destination path collides with an image tag/target string; generated asset lists where the same logical name is reused by different asset types across versions.
Related errors
- different targets for same file %s: %s vs %s
- different sha for same file %s: %s vs %s
- unable to marshal YAML: %v
- unable to marshal JSON: %v
- unable to find any containerd binaries in assets
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/cb325d1fc4f9033f.
Report an issue: GitHub.