apache/beam · error

input must be a slice or array

Error message

input %v must be a slice or array

What it means

AddElementList accepts a single container argument of any type and expands it into elements. It requires the argument to be a Go slice or array; any other kind (map, string, scalar, nil) is rejected with this error.

Solutions

  1. Wrap the element in a slice: AddElementList(ts, []int{1,2}) instead of AddElementList(ts, 1)
  2. Convert maps to slices before passing
  3. Ensure the value is non-nil and a real slice/array type
  4. Note: an empty non-nil slice is valid and adds no elements

Example fix

// before
cfg.AddElementList(0, 42)
// after
cfg.AddElementList(0, []int{42})
Defensive patterns

Strategy: type-guard

Validate before calling

v := reflect.ValueOf(elements)
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { return fmt.Errorf("need slice/array, got %s", v.Kind()) }

Type guard

func isSliceOrArray(v any) bool {
    k := reflect.ValueOf(v).Kind()
    return k == reflect.Slice || k == reflect.Array
}

Try / catch

if err := cfg.AddElementList(ts, elems); err != nil {
    t.Fatalf("AddElementList input must be a slice/array: %v", err)
}

Prevention

When it happens

Trigger: Calling Config.AddElementList(ts, x) where x is not a slice or array — e.g. a map, a single scalar value, or an untyped nil.

Common situations: Passing a single element instead of a list by mistake, passing a map when a slice of keys/values was intended, or passing a typed nil slice variable.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

		}
		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 {
		return fmt.Errorf("input %v must be a slice or array", elements)
	}

	var inputs []any
	for i := 0; i < val.Len(); i++ {
		inputs = append(inputs, val.Index(i).Interface())
	}
	return c.AddElements(timestamp, inputs...)
}

// Create inserts a TestStream primitive into a pipeline, taking a scope and a Config object and
// producing an output PCollection. The TestStream must be the first PTransform in the
// pipeline.
func Create(s beam.Scope, c Config) beam.PCollection {
	pyld := protox.MustEncode(c.createPayload())
	outputs := []beam.FullType{c.elmType}

	output := beam.External(s, urn, pyld, []beam.PCollection{}, outputs, false)

View on GitHub (pinned to 12126d8942)