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

  1. Construct values with `util.FromInt(v)` or `util.FromString(s)` instead of struct literals
  2. If converting from k8s `intstr.IntOrString`, map by checking `k8sVal.Type == intstr.Int` rather than copying the numeric Type value
  3. 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

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


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