apache/beam · error

Unexpected type: %v

Error message

Unexpected type: %v

What it means

inferCoder in sdks/go/pkg/beam/coder.go panics with "Unexpected type: %v" when the given FullType matches neither the atomic-kind switch nor any known composite kind, hitting the outer default. Every NewCoder, NewElementEncoder, NewElementDecoder, and coder-inference path funnels through this function, so an unclassifiable type is a fail-fast internal invariant violation.

Source

Thrown at sdks/go/pkg/beam/coder.go:274

		switch t.Type() {
		case typex.KVType:
			return &coder.Coder{Kind: coder.KV, T: t, Components: c}, nil
		case typex.CoGBKType:
			return &coder.Coder{Kind: coder.CoGBK, T: t, Components: c}, nil
		case typex.WindowedValueType:
			// TODO(herohde) 4/15/2018: do we ever infer W types now that PCollections
			// are non-windowed? We either need to know the windowing strategy or
			// we should remove this case.
			return &coder.Coder{Kind: coder.WindowedValue, T: t, Components: c, Window: coder.NewGlobalWindow()}, nil
		case typex.ShardedKeyType:
			return &coder.Coder{Kind: coder.ShardedKey, T: t, Components: c}, nil

		default:
			panic(fmt.Sprintf("Unexpected composite type: %v", t))
		}
	default:
		panic(fmt.Sprintf("Unexpected type: %v", t))
	}
}

func inferCoders(list []FullType) ([]*coder.Coder, error) {
	var ret []*coder.Coder
	for _, t := range list {
		c, err := inferCoder(t)
		if err != nil {
			return nil, err
		}
		ret = append(ret, c)
	}
	return ret, nil
}

// protoEnc marshals the supplied proto.Message.
func protoEnc(in T) ([]byte, error) {
	var p protoreflect.ProtoMessage

View on GitHub (pinned to 12126d8942)

Solutions

  1. Identify the type from the panic message and replace it with a standard Beam-representable type (primitive, struct, slice, map, KV).
  2. If the type is legitimately new, add a case to inferCoder mapping its kind to a coder.Coder Kind.
  3. Align Beam SDK versions across pipeline submission and worker.
  4. Validate custom types with typex.New and confirm the kind is supported before building coders.

Example fix

// before
default:
    panic(fmt.Sprintf("Unexpected type: %v", t))
// after
case typex.MyKind:
    return &coder.Coder{Kind: coder.Custom, T: t}, nil
default:
    panic(fmt.Sprintf("Unexpected type: %v", t))
Defensive patterns

Strategy: validation

Validate before calling

if t == nil || t.Kind() == 0 {
    return nil, fmt.Errorf("cannot infer coder for unknown type: %v", t)
}
if _, err := beam.NewCoder(t.Type()); err != nil {
    return nil, fmt.Errorf("type not coder-compatible: %w", err)
}

Type guard

func isCoderSupported(t typex.FullType) bool {
    return t != nil && typex.IsKnownKind(t.Kind())
}

Try / catch

func inferSafe(t typex.FullType) (c *coder.Coder, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("coder inference panicked for type %v: %v", t, r)
        }
    }()
    return beam.NewCoder(t.Type())
}

Prevention

When it happens

Trigger: Passing a FullType whose typex.Kind is outside the enumerated supported kinds (e.g. a custom typex.Kind from an extension, or a hand-constructed FullType) into NewCoder / NewElementEncoder / NewElementDecoder / inferCoders.

Common situations: Third-party Beam extensions introducing new types; hand-built typex.FullType values in tests or wrappers; version skew where one side understands a type the other does not.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/ada9f3fdd68a9b9d. Report an issue: GitHub.