{"record":{"id":"c41c96305bf1128d","repo":"apache/beam","slug":"decoding-a-v-row-decoder","errorCode":null,"errorMessage":"decoding a %v","messagePattern":"decoding a (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/coder/row_decoder.go","lineNumber":122,"sourceCode":"\tif isPtr {\n\t\treturn func(r io.Reader) (any, error) {\n\t\t\trv := reflect.New(t)\n\t\t\terr := dec(rv.Elem(), r)\n\t\t\t// Wrap handles nil cases, but io.EOF should be checked explicitly.\n\t\t\tif err == io.EOF {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn rv.Interface(), errors.Wrapf(err, \"decoding a *%v\", t)\n\t\t}, nil\n\t}\n\treturn func(r io.Reader) (any, error) {\n\t\trv := reflect.New(t)\n\t\terr := dec(rv.Elem(), r)\n\t\t// Wrap handles nil cases, but io.EOF should be checked explicitly.\n\t\tif err == io.EOF {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn rv.Elem().Interface(), errors.Wrapf(err, \"decoding a %v\", t)\n\t}, nil\n}\n\n// decoderForStructReflect returns a reflection based decoder function for the\n// given struct type.\nfunc (b *RowDecoderBuilder) decoderForStructReflect(t reflect.Type) (func(reflect.Value, io.Reader) error, error) {\n\tvar coder typeDecoderReflect\n\tcoder.typ = t\n\tfor i := 0; i < t.NumField(); i++ {\n\t\ti := i // avoid alias issues in the closures.\n\t\tsf := t.Field(i)\n\t\tisUnexported := sf.PkgPath != \"\"\n\t\tif sf.Anonymous {\n\t\t\tft := sf.Type\n\t\t\tif ft.Kind() == reflect.Ptr {\n\t\t\t\t// If a struct embeds a pointer to an unexported type,\n\t\t\t\t// it is not possible to set a newly allocated value\n\t\t\t\t// since the field is unexported.","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/coder/row_decoder.go#L104-L140","documentation":"The row decoder for struct (non-pointer) types wraps any non-EOF decode error with \"decoding a %v\", after decoding into a freshly allocated value. Like the pointer variant, io.EOF passes through unwrapped for end-of-stream detection. It signals that the encoded row bytes could not be decoded into the target struct type.","triggerScenarios":"Decoding a row stream into T where a field fails to decode due to layout/schema mismatch, a truncated stream, or a coder mismatch between the write and read sides.","commonSituations":"Schema drift between pipeline stages; reading data written with a different Beam version or a non-row coder; byte corruption in shuffle storage.","solutions":["Align writer and reader struct definitions/schemas","Inspect the wrapped underlying error for the failing field","Re-encode affected data after schema changes","Pin matching Beam versions across stages"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"v, err := decodeRow(r)\nif err != nil {\n    if errors.Is(err, io.EOF) { return nil, io.EOF }\n    return nil, fmt.Errorf(\"row decode failed for %T, check schema drift: %w\", v, err)\n}","preventionTips":["Align writer and reader struct definitions/schemas before deployment","Inspect the wrapped inner error to find the failing field","Re-encode affected data after schema changes","Use matching Beam versions on both sides of the coder"],"tags":["go","beam","row-decoder","decoding","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}