{"record":{"id":"ea4e3981ee040cf0","repo":"apache/beam","slug":"invalid-coder","errorCode":null,"errorMessage":"invalid coder","messagePattern":"invalid coder","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/coder.go","lineNumber":343,"sourceCode":"\n// jsonEnc encodes the supplied value in JSON.\nfunc jsonEnc(in T) ([]byte, error) {\n\treturn jsonx.Marshal(in)\n}\n\n// jsonDec decodes the supplied JSON into an instance of the supplied type.\nfunc jsonDec(t reflect.Type, in []byte) (T, error) {\n\tval := reflect.New(t)\n\tif err := jsonx.Unmarshal(val.Interface(), in); err != nil {\n\t\treturn nil, err\n\t}\n\treturn val.Elem().Interface(), nil\n}\n\nfunc newJSONCoder(t reflect.Type) (*coder.CustomCoder, error) {\n\tc, err := coder.NewCustomCoder(\"json\", t, jsonEnc, jsonDec)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"invalid coder\")\n\t}\n\treturn c, nil\n}\n\n// These maps and mutexes are actuated per element, which can be expensive.\nvar (\n\tencMu      sync.Mutex\n\tschemaEncs = map[reflect.Type]func(any, io.Writer) error{}\n\n\tdecMu      sync.Mutex\n\tschemaDecs = map[reflect.Type]func(io.Reader) (any, error){}\n)\n\n// schemaEnc encodes the supplied value as beam schema.\nfunc schemaEnc(t reflect.Type, in T) ([]byte, error) {\n\tswitch t.Kind() {\n\tcase reflect.Slice, reflect.Array:\n\t\tt = t.Elem()","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/coder.go#L325-L361","documentation":"newJSONCoder wraps coder.NewCustomCoder(\"json\", t, jsonEnc, jsonDec). NewCustomCoder validates that the type is actually encodable/decodable by the supplied encoder/decoder functions; if validation fails (e.g. the JSON encoder/decoder function signatures do not type-check against the element type, or the type cannot be used with reflection-based JSON coding), the error is wrapped as \"invalid coder\".","triggerScenarios":"inferCoder reaches newJSONCoder(et) for a type it deemed JSON-codable, but coder.NewCustomCoder rejects the (type, encoder, decoder) triple — typically because jsonEnc/jsonDec cannot legally encode/decode that reflect.Type, or the type has no concrete representation (e.g. unexported/recursive structures rejected by the custom-coder validator).","commonSituations":"Custom coder registration with mismatched encoder/decoder signatures; elements whose types fail reflection-based JSON encode validation (e.g. channels, funcs, or unexported fields in nested structs passed through generic pipelines).","solutions":["Inspect the wrapped cause (errors.Wrapf preserves it) via %v/%+v on the returned error to see why NewCustomCoder rejected the type.","Change the PCollection element to a JSON-serializable concrete struct with exported fields.","Register a custom coder with your own encoder/decoder functions whose signatures match the element type: coder.NewCustomCoder(name, typ, enc, dec) and pass it explicitly instead of relying on JSON inference.","Avoid element types containing channels, funcs, or cyclic references; those cannot be codified."],"exampleFix":"// before\nbeam.ParDo(s, &Fn{}, col) // element type contains a func field -> invalid coder\n\n// after\ntype MyElem struct { Value string } // JSON-safe concrete struct\nbeam.ParDo(s, &Fn{}, col, beam.TypeDefinition{... reflect.TypeOf(MyElem{})})","handlingStrategy":"validation","validationCode":"if _, err := coder.NewCustomCoder(\"json\", reflect.TypeOf(elem{}), jsonEnc, jsonDec); err != nil {\n  return fmt.Errorf(\"element type not JSON-codable: %w\", err)\n}","typeGuard":"func isJSONCodable(t reflect.Type) bool {\n  _, err := coder.NewCustomCoder(\"json\", t, jsonEnc, jsonDec)\n  return err == nil\n}","tryCatchPattern":"c, err := newJSONCoder(t)\nif err != nil {\n  return fmt.Errorf(\"element type %v rejected by JSON coder: %w\", t, err)\n}","preventionTips":["Keep PCollection element types JSON-serializable: exported fields, no channels/funcs/cycles.","Test coder construction at pipeline-build time rather than at runtime.","Wrap coder errors with the offending reflect.Type to make diagnostics actionable.","Prefer explicit custom coders over relying on inference for non-trivial types."],"tags":["go","beam","coder","json"],"backgroundTag":"invalid-argument-value","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"}