GoogleContainerTools/skaffold · error
only one element in set %s can be set. got %s and %s
Error message
only one element in set %s can be set. got %s and %s
What it means
For fields in a oneOf set (mutually exclusive config alternatives), oneOfTag.Process verifies no sibling field of the same set is also non-zero. If two members are set (e.g. both `docker` and `kaniko` build strategies, or two execution modes), it returns 'only one element in set %s can be set', naming the set and the two conflicting fields.
Source
Thrown at pkg/skaffold/yamltags/tags.go:235
}
oot.oneOfSets[oot.setName][oot.Field.Name] = struct{}{}
return nil
}
func (oot *oneOfTag) Process(val reflect.Value) error {
if isZeroValue(val) {
return nil
}
// This must exist because process is always called after Load.
oneOfSet := oot.oneOfSets[oot.setName]
for otherField := range oneOfSet {
if otherField == oot.Field.Name {
continue
}
field := oot.Parent.FieldByName(otherField)
if !isZeroValue(field) {
return fmt.Errorf("only one element in set %s can be set. got %s and %s", oot.setName, otherField, oot.Field.Name)
}
}
return nil
}
type skipTrimTag struct {
Field reflect.StructField
}
func (tag *skipTrimTag) Load(s []string) error {
return nil
}
func (tag *skipTrimTag) Process(val reflect.Value) error {
if isZeroValue(val) {
if tags, ok := tag.Field.Tag.Lookup("yaml"); ok {
return fmt.Errorf("skipTrim value not set: %s", strings.Split(tags, ",")[0])
}View on GitHub (pinned to a1189de023)
Solutions
- Remove one of the two fields named in the error from skaffold.yaml, keeping the alternative you intend
- Comment out the unused strategy block rather than leaving empty-looking keys that may parse as set
- Use `skaffold fix` or `skaffold init` to regenerate a valid single-choice config
- Check indentation — a misnested key can accidentally land in the sibling field's position
Example fix
// before (skaffold.yaml) — both set
build:
artifacts:
- image: foo
kaniko: {}
docker: {}
// after
build:
artifacts:
- image: foo
docker: {} Defensive patterns
Strategy: validation
Validate before calling
// ensure only one member of a oneOf set is present in the decoded config
func oneOfSet(m map[string]interface{}, members []string) error {
var set []string
for _, k := range members {
if v, ok := m[k]; ok && v != nil && v != "" {
set = append(set, k)
}
}
if len(set) > 1 {
return fmt.Errorf("only one of %v can be set; got %v", members, set)
}
return nil
} Type guard
func exactlyOneSet(flags ...bool) bool {
n := 0
for _, f := range flags { if f { n++ } }
return n == 1
} Try / catch
if err != nil && strings.Contains(err.Error(), "only one element in set") {
// parse set + two field names from the message, drop the unwanted one from config
} Prevention
- Keep only one strategy block (e.g. one executionMode / one build env) in skaffold.yaml
- Comment out unused alternative blocks entirely when switching strategies
- Validate merged config files for duplicate alternatives before applying
- Use `skaffold init` to regenerate clean single-choice configs
When it happens
Trigger: A decoded skaffold.yaml supplies values for two fields that belong to the same oneOf set on a struct (e.g. both `exec` and `docker` in a build execution environment, or both `docker` and `kubernetesCluster` execution modes for verify), then validation runs.
Common situations: Merging config files/snippets and keeping both alternatives; leftover key from a previous strategy plus a newly added one; auto-generated config setting defaults alongside user overrides.
Related errors
- missing apiVersion
- artifact %s has invalid Jib plugin type '%s'
- required value not set: %s
- skipTrim value not set: %s
- invalid local-registry-hosting ConfigMap
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/ca89e86972f1fffd.
Report an issue: GitHub.