{"record":{"id":"f66a7be931e68d06","repo":"apache/beam","slug":"decoding-a-v","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":112,"sourceCode":"\t// Pointers become the value type for decomposition.\n\tif t.Kind() == reflect.Ptr {\n\t\tisPtr = true\n\t\tt = t.Elem()\n\t}\n\tdec, err := b.decoderForStructReflect(t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\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","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/coder/row_decoder.go#L94-L130","documentation":"The row decoder for pointer-to-struct types wraps any non-EOF decode error with \"decoding a *%v\". It allocates a new value of type t, decodes into its element, and returns the wrapped error if field decoding fails. io.EOF is deliberately re-raised unwrapped so callers can detect clean end-of-stream. The wrapped error means the encoded row bytes did not match the expected struct layout.","triggerScenarios":"Decoding a row stream into *T where a field's bytes fail to decode — schema mismatch, truncated data, or the wrong coder used at write time.","commonSituations":"Schema evolution (field added/removed/retyped) between writer and reader; replaying data encoded by an older Beam version; reading a stream written by an entirely different coder.","solutions":["Compare the writer's schema with the reader's struct and reconcile fields","Check the wrapped underlying error to find the offending field","Re-encode the data after schema changes, or use compatible field evolution","Ensure both pipeline stages use the same Beam version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify schema compatibility before decoding\nif !schemasCompatible(writerSchema, readerSchema) {\n    return fmt.Errorf(\"writer schema %v incompatible with reader struct %T\", writerSchema, reader)\n}","typeGuard":null,"tryCatchPattern":"v, err := decodeRowPtr(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\", err)\n}","preventionTips":["Keep writer and reader struct definitions in a shared package","Handle io.EOF separately — it passes through unwrapped","Re-encode data after schema changes; avoid silent field retyping","Pin the same Beam version across pipeline stages"],"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"}