{"record":{"id":"e4fd70bc8cabfe2d","repo":"micro/go-micro","slug":"failed-to-marshal-object","errorCode":null,"errorMessage":"Failed to marshal object","messagePattern":"Failed to marshal object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"store/nats-js-kv/nats.go","lineNumber":238,"sourceCode":"\t\topt.Database = n.opts.Database\n\t}\n\n\tif opt.Table == \"\" {\n\t\topt.Table = n.opts.Table\n\t}\n\n\tstore, err := n.mustGetBucketByName(opt.Database)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tb, err := json.Marshal(KeyValueEnvelope{\n\t\tKey:      rec.Key,\n\t\tData:     rec.Value,\n\t\tMetadata: rec.Metadata,\n\t})\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Failed to marshal object\")\n\t}\n\n\tif _, err := store.Put(n.NatsKey(opt.Table, rec.Key), b); err != nil {\n\t\treturn errors.Wrapf(err, \"Failed to store data in bucket '%s'\", n.NatsKey(opt.Table, rec.Key))\n\t}\n\n\treturn nil\n}\n\n// Delete removes the record with the corresponding key from the store.\nfunc (n *natsStore) Delete(key string, opts ...store.DeleteOption) error {\n\tif err := n.initConn(); err != nil {\n\t\treturn err\n\t}\n\n\topt := store.DeleteOptions{}\n\n\tfor _, o := range opts {","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/store/nats-js-kv/nats.go#L220-L256","documentation":"Returned by Write when json.Marshal of the KeyValueEnvelope wrapping the record fails before it is put into the bucket. The envelope contains the record key, data bytes, and metadata map, so marshal failures are rare but possible. pkg/errors wraps the underlying json error.","triggerScenarios":"Calling store.Write(rec) where rec.Metadata contains a value that the encoding/json package cannot marshal, such as channels, funcs, complex numbers, or a struct implementing MarshalJSON that returns an error.","commonSituations":"Developers storing metadata maps built from arbitrary Go values (e.g. containing func or chan fields from other subsystems) into go-micro records; passing unsupported types through middleware that copies values into Metadata.","solutions":["Inspect rec.Metadata for unsupported types (chan, func, complex) and remove or convert them to JSON-safe values","Implement json.Marshaler on custom metadata value types that fail to marshal","Marshal the record yourself in a test (json.Marshal on the same fields) to reproduce and pinpoint the offending field","Downgrade to storing a json.RawMessage or []byte representation in Data instead of embedding raw structures in Metadata"],"exampleFix":"// before\nrec := &store.Record{Key: \"k\", Value: data, Metadata: map[string]interface{}{\"cb\": make(chan int)}}\nstore.Write(rec)\n// after\nrec := &store.Record{Key: \"k\", Value: data, Metadata: map[string]interface{}{\"id\": \"123\"}}\nstore.Write(rec)","handlingStrategy":"try-catch","validationCode":"if _, err := json.Marshal(rec.Metadata); err != nil {\n    return fmt.Errorf(\"record metadata not JSON-serializable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := st.Write(rec); err != nil {\n    if strings.Contains(err.Error(), \"Failed to marshal object\") {\n        log.Printf(\"dropping unserializable metadata for key %s\", rec.Key)\n    }\n    return err\n}","preventionTips":["Keep Metadata values limited to JSON-safe types (string, numbers, bool, nested maps/slices)","Unit-test writes of representative records including their metadata","Avoid copying arbitrary structs into Metadata; store complex values in rec.Value as bytes","Consider json.RawMessage for pre-serialized metadata values"],"tags":["json","serialization","store"],"backgroundTag":"json-marshal-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}