apache/beam · error

Nested FullValues must be nested as pointers.

Error message

Nested FullValues must be nested as pointers.

What it means

When encoding composite types, convertIfNeeded wraps values for FullValue-based coders. A nested FullValue must be passed as *FullValue (a pointer); passing a FullValue by value cannot be handled (the function needs a stable, possibly overwritable slot), so it panics. This indicates the value was constructed/typed incorrectly upstream.

Source

Thrown at sdks/go/pkg/beam/core/runtime/exec/coder.go:638

// the contents of the first element, but returning the FullValue unchanged
// if it has two elements.
//
// Technically drops window and timestamp info, so only use when those are
// expected to be empty.
func elideSingleElmFV(fv *FullValue) any {
	if fv.Elm2 == nil {
		return fv.Elm
	}
	return fv
}

// convertIfNeeded reuses Wrapped KVs if needed, but accepts pointer
// to a pre-allocated non-nil *FullValue for overwriting and use.
func convertIfNeeded(v any, allocated *FullValue) *FullValue {
	if fv, ok := v.(*FullValue); ok {
		return fv
	} else if _, ok := v.(FullValue); ok {
		panic("Nested FullValues must be nested as pointers.")
	}
	*allocated = FullValue{Elm: v}
	return allocated
}

type nullableEncoder struct {
	inner ElementEncoder
	be    boolEncoder
}

func (n *nullableEncoder) Encode(value *FullValue, writer io.Writer) error {
	if value.Elm == nil {
		if err := n.be.Encode(&FullValue{Elm: false}, writer); err != nil {
			return err
		}
		return nil
	}
	if err := n.be.Encode(&FullValue{Elm: true}, writer); err != nil {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the nested value to a *FullValue pointer (&fv) before encoding.
  2. If you only need to wrap a plain value, pass the raw value — convertIfNeeded wraps non-FullValue values automatically.
  3. Fix the producer code that constructs the nested element to use pointers for nested FullValues.

Example fix

// before
elm := exec.FullValue{Elm: x}
Encode(c, elm, w) // panics: value-typed nested FullValue
// after
elm := &exec.FullValue{Elm: x}
Encode(c, elm, w)
Defensive patterns

Strategy: type-guard

Validate before calling

if fv, ok := v.(exec.FullValue); ok {
	v = &fv // convert value-typed FullValue to pointer before encoding
}

Type guard

func isValueFullValue(v any) bool {
	_, ok := v.(exec.FullValue)
	return ok
}

Try / catch

// recover at pipeline-construction boundary
defer func() {
	if r := recover(); r != nil {
		err = fmt.Errorf("coder error: %v", r)
	}
}()

Prevention

When it happens

Trigger: Encoding an element where a nested field was stored as a FullValue value (not pointer) inside a KV/struct being encoded via exec.Encode or ProcessElement.

Common situations: Custom coders or user DoFns that build FullValue structs manually and forget to take the address; changes in the exec package's expectations when upgrading Beam versions.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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