{"record":{"id":"cd1d3177446c4eff","repo":"hyperledger/fabric","slug":"error-unmarshalling-json-data-cd1d31","errorCode":null,"errorMessage":"error unmarshalling json data","messagePattern":"error unmarshalling json data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go","lineNumber":46,"sourceCode":"\ntype keyValue struct {\n\tkey      string\n\trevision string\n\t*statedb.VersionedValue\n}\n\ntype jsonValue map[string]any\n\nfunc tryCastingToJSON(b []byte) (isJSON bool, val jsonValue) {\n\tvar jsonVal map[string]any\n\terr := json.Unmarshal(b, &jsonVal)\n\treturn err == nil, jsonVal\n}\n\nfunc castToJSON(b []byte) (jsonValue, error) {\n\tvar jsonVal map[string]any\n\terr := json.Unmarshal(b, &jsonVal)\n\terr = errors.Wrap(err, \"error unmarshalling json data\")\n\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)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go#L28-L64","documentation":"castToJSON unmarshals raw bytes into a map[string]any jsonValue and wraps any json.Unmarshal failure with \"error unmarshalling json data\". It is used by removeJSONRevision to strip the _rev field from retrieved CouchDB documents, so the error means a document's stored bytes are not a valid JSON object. Note the current implementation returns the (possibly nil) jsonVal along with a non-nil wrapped error.","triggerScenarios":"removeJSONRevision processing a CouchDB document whose jsonValue bytes fail to parse as a JSON object — e.g. the stored value is null, a scalar/array, or truncated bytes.","commonSituations":"Corrupted CouchDB documents; documents written directly to CouchDB externally in a non-object JSON form; version mismatch where an older Fabric wrote data in a shape the current code cannot parse.","solutions":["Inspect the offending CouchDB document (curl GET /dbname/docid) and verify it is a valid JSON object.","Restore corrupted documents from a backup or rebuild the state database (drop and re-read from the blockchain).","Ensure only the peer writes to CouchDB — external modifications can introduce non-object documents."],"exampleFix":"// before: doc stored as non-object JSON\n{\"_id\":\"x\"}  // OK\n// a document stored as \"just a string\" fails; rewrite it as an object:\ncurl -X PUT https://admin:pass@localhost:5984/db/x -d '{\"_id\":\"x\",\"data\":\"value\"}'","handlingStrategy":"type-guard","validationCode":"// verify stored document is a JSON object before processing\nvar probe map[string]any\nif err := json.Unmarshal(docBytes, &probe); err != nil || probe == nil { /* corrupt or non-object document */ }","typeGuard":"func isJSONMap(b []byte) bool {\n    var m map[string]any\n    return json.Unmarshal(b, &m) == nil && m != nil\n}","tryCatchPattern":"jsonVal, err := castToJSON(b)\nif err != nil {\n    if strings.Contains(err.Error(), \"error unmarshalling json data\") {\n        // restore from backup or rebuild state db for this document\n    }\n    return err\n}","preventionTips":["Restrict CouchDB write access to the peer only.","Back up CouchDB data and validate after restores.","Ensure documents written externally (if any) are JSON objects.","Rebuild the state database from the blockchain when corruption is detected."],"tags":["couchdb","json","unmarshal","corruption"],"backgroundTag":"json-unmarshal-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"}