hyperledger/fabric · error
error marshalling json data
Error message
error marshalling json data
What it means
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.
Source
Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go:65
return jsonVal, err
}
func (v jsonValue) checkReservedFieldsNotPresent() error {
for fieldName := range v {
if fieldName == versionField || strings.HasPrefix(fieldName, "_") {
return errors.Errorf("field [%s] is not valid for the CouchDB state database", fieldName)
}
}
return nil
}
func (v jsonValue) removeRevField() {
delete(v, revField)
}
func (v jsonValue) toBytes() ([]byte, error) {
jsonBytes, err := json.Marshal(v)
err = errors.Wrap(err, "error marshalling json data")
return jsonBytes, err
}
func couchDocToKeyValue(doc *couchDoc) (*keyValue, error) {
docFields, err := validateAndRetrieveFields(doc)
if err != nil {
return nil, err
}
version, metadata, err := decodeVersionAndMetadata(docFields.versionAndMetadata)
if err != nil {
return nil, err
}
return &keyValue{
docFields.id, docFields.revision,
&statedb.VersionedValue{
Value: docFields.value,
Version: version,
Metadata: metadata,View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
value := jsonValue{"data": make(chan int)}
bytes, err := value.toBytes()
// after
value := jsonValue{"data": 42}
bytes, err := value.toBytes() Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := json.Marshal(value); err != nil {
return fmt.Errorf("value not JSON-marshalable: %w", err)
} Type guard
func isJSONSafe(v interface{}) bool {
_, err := json.Marshal(v)
return err == nil
} Try / catch
bytes, err := v.toBytes()
if err != nil {
logger.Errorf("toBytes failed: %+v", err)
return fmt.Errorf("state value serialization failed: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Custom code paths or tests constructing jsonValue from arbitrary Go structures instead of decoded JSON; injecting unsupported Go types into the state value map.
Related errors
- failed to marshal savepoint data
- failed to unmarshal savepoint data
- failed to marshal channel metadata
- failed to unmarshal channel metadata
- failed to marshal dataformatInfo [%#v]
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/06837546b3f97b35.
Report an issue: GitHub.