apache/beam · error

encoding value failed, got

Error message

encoding value %v failed, got %v

What it means

AddElements encodes each element with the Beam element coder before embedding it in the TestStream payload. If the coder's Encode call fails (e.g. the type has no built-in coder or the value cannot be serialized), this error wraps the encoding failure.

Solutions

  1. Use only types with built-in Beam coders (primitives, strings, byte slices, simple structs of those)
  2. Register a custom coder via beam.Encoder/beam.CustomCoder for the element type
  3. Convert elements to an encodable type before adding
  4. Inspect the wrapped %v error for the specific encoding failure

Example fix

// before
cfg.AddElements(0, myUnregisteredStruct{...}) // no coder
// after
coder := beam.NewCustomCoder("mystruct", reflect.TypeOf(myStruct{}), encodeFn, decodeFn)
// or use encodable element types
cfg.AddElements(0, "plain-string-element")
Defensive patterns

Strategy: validation

Validate before calling

enc := beam.NewElementEncoder(reflect.TypeOf(elems[0]))
for _, e := range elems {
    var buf bytes.Buffer
    if err := enc.Encode(e, &buf); err != nil { return err } // pre-flight
}

Try / catch

if err := cfg.AddElements(ts, elems...); err != nil {
    if strings.Contains(err.Error(), "encoding value") {
        t.Fatalf("element not encodable with built-in coder: %v", err)
    }
    t.Fatal(err)
}

Prevention

When it happens

Trigger: Adding elements of a type without a built-in Beam coder (per the API doc: element types must have built-in coders), or a value that fails encoding (e.g. unencodable struct fields).

Common situations: Using custom structs, maps, or interfaces as TestStream elements; passing unsupported types like func or chan; forgetting to register a custom coder.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/testing/teststream/teststream.go:129

// Element types must have built-in coders in Beam.
func (c *Config) AddElements(timestamp int64, elements ...any) error {
	t := reflect.TypeOf(elements[0])
	if c.elmType == nil {
		c.elmType = typex.New(t)
	} else if c.elmType.Type() != t {
		return fmt.Errorf("element type mismatch, previous additions were of type %v, tried to add type %v", c.elmType, t)
	}
	for i, ele := range elements {
		if reflect.TypeOf(ele) != c.elmType.Type() {
			return fmt.Errorf("element %d was type %T, previous additions were of type %v", i, ele, c.elmType)
		}
	}
	newElements := []*pipepb.TestStreamPayload_TimestampedElement{}
	enc := beam.NewElementEncoder(t)
	for _, e := range elements {
		var buf bytes.Buffer
		if err := enc.Encode(e, &buf); err != nil {
			return fmt.Errorf("encoding value %v failed, got %v", e, err)
		}
		newElements = append(newElements, &pipepb.TestStreamPayload_TimestampedElement{EncodedElement: buf.Bytes(), Timestamp: timestamp})
	}
	addElementsEvent := &pipepb.TestStreamPayload_Event_AddElements{Elements: newElements}
	elementEvent := &pipepb.TestStreamPayload_Event_ElementEvent{ElementEvent: addElementsEvent}
	c.events = append(c.events, &pipepb.TestStreamPayload_Event{Event: elementEvent})
	return nil
}

// AddElementList inserts a slice of elements into the stream at the specified event timestamp. Must be called with
// at least one element.
//
// Calls into AddElements, which panics if an inserted type does not match a previously inserted element type.
//
// Element types must have built-in coders in Beam.
func (c *Config) AddElementList(timestamp int64, elements any) error {
	val := reflect.ValueOf(elements)
	if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {

View on GitHub (pinned to 12126d8942)