{"record":{"id":"06837546b3f97b35","repo":"hyperledger/fabric","slug":"error-marshalling-json-data-068375","errorCode":null,"errorMessage":"error marshalling json data","messagePattern":"error marshalling json data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go","lineNumber":65,"sourceCode":"\treturn jsonVal, err\n}\n\nfunc (v jsonValue) checkReservedFieldsNotPresent() error {\n\tfor fieldName := range v {\n\t\tif fieldName == versionField || strings.HasPrefix(fieldName, \"_\") {\n\t\t\treturn errors.Errorf(\"field [%s] is not valid for the CouchDB state database\", fieldName)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (v jsonValue) removeRevField() {\n\tdelete(v, revField)\n}\n\nfunc (v jsonValue) toBytes() ([]byte, error) {\n\tjsonBytes, err := json.Marshal(v)\n\terr = errors.Wrap(err, \"error marshalling json data\")\n\treturn jsonBytes, err\n}\n\nfunc couchDocToKeyValue(doc *couchDoc) (*keyValue, error) {\n\tdocFields, err := validateAndRetrieveFields(doc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tversion, metadata, err := decodeVersionAndMetadata(docFields.versionAndMetadata)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &keyValue{\n\t\tdocFields.id, docFields.revision,\n\t\t&statedb.VersionedValue{\n\t\t\tValue:    docFields.value,\n\t\t\tVersion:  version,\n\t\t\tMetadata: metadata,","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go#L47-L83","documentation":"toBytes serializes a jsonValue map into JSON bytes for storage in CouchDB. If json.Marshal fails, the underlying error is wrapped with 'error marshalling json data'. This is nearly always caused by an unsupported value type (channels, funcs, cycles) rather than malformed field names.","triggerScenarios":"jsonValue contains a value that the encoding/json package cannot marshal, such as a channel, function, complex number, or a cyclic structure, when the value is converted to bytes for a couchDoc.","commonSituations":"Custom code paths or tests constructing jsonValue from arbitrary Go structures instead of decoded JSON; injecting unsupported Go types into the state value map.","solutions":["Inspect the wrapped cause in the log (%+v prints the original json.Marshal error and offending type)","Ensure the jsonValue only holds JSON-decodable types (map[string]interface{}, string, float64, bool, nil, slices)","Marshal data to JSON at the chaincode boundary so stored values are already plain JSON"],"exampleFix":"// before\nvalue := jsonValue{\"data\": make(chan int)}\nbytes, err := value.toBytes()\n// after\nvalue := jsonValue{\"data\": 42}\nbytes, err := value.toBytes()","handlingStrategy":"try-catch","validationCode":"if _, err := json.Marshal(value); err != nil {\n    return fmt.Errorf(\"value not JSON-marshalable: %w\", err)\n}","typeGuard":"func isJSONSafe(v interface{}) bool {\n    _, err := json.Marshal(v)\n    return err == nil\n}","tryCatchPattern":"bytes, err := v.toBytes()\nif err != nil {\n    logger.Errorf(\"toBytes failed: %+v\", err)\n    return fmt.Errorf(\"state value serialization failed: %w\", err)\n}","preventionTips":["Only store JSON-decoded values in jsonValue maps","Avoid channels, funcs, and cyclic references in state values","Pre-marshal values to []byte at the chaincode boundary"],"tags":["json","marshalling","couchdb","fabric-ledger"],"backgroundTag":"json-marshalling-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}