{"record":{"id":"d0c1a2c2bd08cc19","repo":"apache/beam","slug":"nested-fullvalues-must-be-nested-as-pointers","errorCode":null,"errorMessage":"Nested FullValues must be nested as pointers.","messagePattern":"Nested FullValues must be nested as pointers\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/exec/coder.go","lineNumber":638,"sourceCode":"// the contents of the first element, but returning the FullValue unchanged\n// if it has two elements.\n//\n// Technically drops window and timestamp info, so only use when those are\n// expected to be empty.\nfunc elideSingleElmFV(fv *FullValue) any {\n\tif fv.Elm2 == nil {\n\t\treturn fv.Elm\n\t}\n\treturn fv\n}\n\n// convertIfNeeded reuses Wrapped KVs if needed, but accepts pointer\n// to a pre-allocated non-nil *FullValue for overwriting and use.\nfunc convertIfNeeded(v any, allocated *FullValue) *FullValue {\n\tif fv, ok := v.(*FullValue); ok {\n\t\treturn fv\n\t} else if _, ok := v.(FullValue); ok {\n\t\tpanic(\"Nested FullValues must be nested as pointers.\")\n\t}\n\t*allocated = FullValue{Elm: v}\n\treturn allocated\n}\n\ntype nullableEncoder struct {\n\tinner ElementEncoder\n\tbe    boolEncoder\n}\n\nfunc (n *nullableEncoder) Encode(value *FullValue, writer io.Writer) error {\n\tif value.Elm == nil {\n\t\tif err := n.be.Encode(&FullValue{Elm: false}, writer); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\tif err := n.be.Encode(&FullValue{Elm: true}, writer); err != nil {","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/exec/coder.go#L620-L656","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Change the nested value to a *FullValue pointer (&fv) before encoding.","If you only need to wrap a plain value, pass the raw value — convertIfNeeded wraps non-FullValue values automatically.","Fix the producer code that constructs the nested element to use pointers for nested FullValues."],"exampleFix":"// before\nelm := exec.FullValue{Elm: x}\nEncode(c, elm, w) // panics: value-typed nested FullValue\n// after\nelm := &exec.FullValue{Elm: x}\nEncode(c, elm, w)","handlingStrategy":"type-guard","validationCode":"if fv, ok := v.(exec.FullValue); ok {\n\tv = &fv // convert value-typed FullValue to pointer before encoding\n}","typeGuard":"func isValueFullValue(v any) bool {\n\t_, ok := v.(exec.FullValue)\n\treturn ok\n}","tryCatchPattern":"// recover at pipeline-construction boundary\ndefer func() {\n\tif r := recover(); r != nil {\n\t\terr = fmt.Errorf(\"coder error: %v\", r)\n\t}\n}()","preventionTips":["Always store nested FullValues as *FullValue in composite elements.","Let convertIfNeeded wrap plain values; only pre-wrap when necessary, and use pointers.","After Beam upgrades, re-test custom coders against exec package expectations."],"tags":["go","panic","beam","coder","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}