GoogleContainerTools/skaffold · error
impossible IntOrString.Type
Error message
impossible IntOrString.Type
What it means
`IntOrString.MarshalYAML` (pkg/skaffold/schema/util/int_string.go:78) serializes a value that can hold either an int or a string, switching on `Type` (Int=0, String=1). The `default` branch is unreachable for correctly constructed values, so this error indicates an IntOrString whose zero-value-ish Type is neither Int nor String — i.e. it was constructed directly with an invalid Type (e.g. `IntOrString{}` with Type left as an out-of-range value) rather than via FromInt/FromString.
Source
Thrown at pkg/skaffold/schema/util/int_string.go:78
val := node.Value
i, err := strconv.Atoi(val)
if err != nil {
*t = FromString(val)
} else {
*t = FromInt(i)
}
return nil
}
// MarshalYAML implements the yaml.Marshaler interface.
func (t IntOrString) MarshalYAML() (interface{}, error) {
switch t.Type {
case Int:
return t.IntVal, nil
case String:
return t.StrVal, nil
default:
return nil, fmt.Errorf("impossible IntOrString.Type")
}
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (t *IntOrString) UnmarshalJSON(value []byte) error {
if value[0] == '"' {
t.Type = String
return json.Unmarshal(value, &t.StrVal)
}
t.Type = Int
return json.Unmarshal(value, &t.IntVal)
}
// MarshalJSON implements the json.Marshaler interface.
func (t IntOrString) MarshalJSON() ([]byte, error) {
switch t.Type {
case Int:
return json.Marshal(t.IntVal)View on GitHub (pinned to a1189de023)
Solutions
- Construct values with `util.FromInt(v)` or `util.FromString(s)` instead of struct literals
- If converting from k8s `intstr.IntOrString`, map by checking `k8sVal.Type == intstr.Int` rather than copying the numeric Type value
- Audit code for direct assignments to the Type field and clamp/normalize them to Int or String before marshaling
Example fix
// before
ios := util.IntOrString{IntVal: 8080} // Type never set correctly
_ = yaml.Marshal(ios) // panics error path
// after
ios := util.FromInt(8080)
out, err := yaml.Marshal(ios) Defensive patterns
Strategy: type-guard
Validate before calling
func ok(v util.IntOrString) bool { return v.Type == util.Int || v.Type == util.String } Type guard
func ok(v util.IntOrString) bool { return v.Type == util.Int || v.Type == util.String } Try / catch
if _, err := yaml.Marshal(cfg); err != nil && strings.Contains(err.Error(), "impossible IntOrString.Type") { return fmt.Errorf("malformed IntOrString: %w", err) } Prevention
- Use util.FromInt/FromString constructors
- Map k8s intstr by inspection, not raw Type
- Unit-test marshaling of config fields
When it happens
Trigger: Programmatic construction of `util.IntOrString` with a Type value other than 0 or 1 (e.g. copied from an API type with different enum values, or a struct left uninitialized by a third-party constructor), followed by yaml.Marshal of a config containing it. Not producible from normal skaffold.yaml parsing, since UnmarshalYAML always sets Type to Int or String.
Common situations: Custom tooling that builds skaffold config structs in Go; mapping from k8s intstr.IntOrString (whose Type uses different iota ordering: String=1, Int=0 in some versions — but any direct assignment of the wrong enum) into skaffold's util.IntOrString without conversion; zero-value struct usage with an explicit bad Type.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- marshalling configuration: %w
- marshaling new config: %w
- marshaling config: %w
- marshalling yaml: %w
- marshalling yaml: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/9c8322ca0d989689.
Report an issue: GitHub.