GoogleContainerTools/skaffold · error
artifact %s cannot use inferred file sync when the ko.main f
Error message
artifact %s cannot use inferred file sync when the ko.main field contains the '...' wildcard. Instead, specify the path to the main package without using wildcards
What it means
When a ko artifact uses inferred file sync (sync.infer), the ko.main field must be a concrete package path. If ko.main contains the Go wildcard '...' (e.g. ./...), Skaffold cannot resolve a single kodata root for inferred sync, so it rejects the combination and asks you to point at the main package directly.
Source
Thrown at pkg/skaffold/schema/validation/validation.go:626
}
cfgErrs = append(cfgErrs, ErrorWithLocation{
Error: fmt.Errorf("artifact %s has invalid Jib plugin type '%s'", a.ImageName, t),
Location: cfg.YAMLInfos.LocateField(cfg.Build.Artifacts[i].JibArtifact, "Type"),
})
}
return
}
// validateKoSync ensures that infer sync patterns contain the `kodata` string, since infer sync for the ko builder only supports static assets.
func validateKoSync(cfg *parser.SkaffoldConfigEntry, artifacts []*latest.Artifact) []ErrorWithLocation {
var cfgErrs []ErrorWithLocation
for i, a := range artifacts {
if a.KoArtifact == nil || a.Sync == nil {
continue
}
if len(a.Sync.Infer) > 0 && strings.Contains(a.KoArtifact.Main, "...") {
cfgErrs = append(cfgErrs, ErrorWithLocation{
Error: fmt.Errorf("artifact %s cannot use inferred file sync when the ko.main field contains the '...' wildcard. Instead, specify the path to the main package without using wildcards", a.ImageName),
Location: cfg.YAMLInfos.LocateField(cfg.Build.Artifacts[i].KoArtifact, "Main"),
})
}
for _, pattern := range a.Sync.Infer {
if !strings.Contains(pattern, "kodata") {
cfgErrs = append(cfgErrs, ErrorWithLocation{
Error: fmt.Errorf("artifact %s has an invalid pattern %s for inferred file sync with the ko builder. The pattern must specify the 'kodata' directory. For instance, if you want to sync all static content, and your main package is in the workspace directory, you can use the pattern 'kodata/**/*'", a.ImageName, pattern),
Location: cfg.YAMLInfos.LocateField(cfg.Build.Artifacts[i].Sync, "Infer"),
})
}
}
}
return cfgErrs
}
// validateArtifactTypes checks that the artifact types are compatible with the specified builder.
func validateArtifactTypes(cfg *parser.SkaffoldConfigEntry, bc latest.BuildConfig) []ErrorWithLocation {
cfgErrs := []ErrorWithLocation{}View on GitHub (pinned to a1189de023)
Solutions
- Change ko.main to the explicit path of the main package (e.g. `./cmd/server`) without '...'
- Remove the sync.infer section if wildcard main is required
- Use explicit sync manual/manual patterns instead of inferred sync
Example fix
# before
build:
artifacts:
- image: myapp
ko:
main: ./...
sync:
infer:
- '**/*.go'
# after
build:
artifacts:
- image: myapp
ko:
main: ./cmd/myapp
sync:
infer:
- '**/*.go' Defensive patterns
Strategy: validation
Validate before calling
if (artifact.ko && artifact.sync?.infer?.length && String(artifact.ko.main || '').includes('...')) {
throw new Error(`artifact '${artifact.imageName}': sync.infer requires ko.main without '...' wildcard`);
} Type guard
function koSyncCompatible(a) {
return !(a?.ko && a?.sync?.infer?.length > 0 && String(a.ko.main ?? '').includes('...'));
} Try / catch
try {
await skaffold.dev();
} catch (e) {
if (/cannot use inferred file sync/.test(e.message)) {
console.error('Point ko.main at the concrete main package path (no ...) or drop sync.infer');
} else throw e;
} Prevention
- Always specify ko.main as an explicit package path (e.g. ./cmd/server)
- Reserve ./... for go build/test commands, not skaffold ko.main
- Prefer explicit sync.manual patterns when wildcard package paths are required
When it happens
Trigger: An artifact with ko: (ko.main containing '...'), a non-empty sync.infer list, processed via ProcessToErrorWithLocation -> validateKoSync.
Common situations: Users copy `main: ./...` from go build habits or module layout docs and then add sync.infer for hot-reload; the combination is unsupported.
Related errors
- sync rule pattern '%s' does not have prefix '%s'
- verify command expects non-zero number of test cases
- CONFIG_MISSING_MANIFEST_FILE_ERR
- INIT_CLOUD_RUN_LOCATION_ERROR
- missing apiVersion
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/be5d30e2a36ef7a9.
Report an issue: GitHub.