{"record":{"id":"d43a9cf0214a393e","repo":"hyperledger/fabric","slug":"error-unmarshalling-txreadwriteset","errorCode":null,"errorMessage":"error unmarshalling TxReadWriteSet","messagePattern":"error unmarshalling TxReadWriteSet","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/unmarshalers.go","lineNumber":179,"sourceCode":"// UnmarshalChaincodeActionPayload unmarshals bytes to a ChaincodeActionPayload\nfunc UnmarshalChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPayload, error) {\n\tcap := &peer.ChaincodeActionPayload{}\n\terr := proto.Unmarshal(capBytes, cap)\n\treturn cap, errors.Wrap(err, \"error unmarshalling ChaincodeActionPayload\")\n}\n\n// UnmarshalChaincodeProposalPayload unmarshals bytes to a ChaincodeProposalPayload\nfunc UnmarshalChaincodeProposalPayload(bytes []byte) (*peer.ChaincodeProposalPayload, error) {\n\tcpp := &peer.ChaincodeProposalPayload{}\n\terr := proto.Unmarshal(bytes, cpp)\n\treturn cpp, errors.Wrap(err, \"error unmarshalling ChaincodeProposalPayload\")\n}\n\n// UnmarshalTxReadWriteSet unmarshals bytes to a TxReadWriteSet\nfunc UnmarshalTxReadWriteSet(bytes []byte) (*rwset.TxReadWriteSet, error) {\n\trws := &rwset.TxReadWriteSet{}\n\terr := proto.Unmarshal(bytes, rws)\n\treturn rws, errors.Wrap(err, \"error unmarshalling TxReadWriteSet\")\n}\n\n// UnmarshalKVRWSet unmarshals bytes to a KVRWSet\nfunc UnmarshalKVRWSet(bytes []byte) (*kvrwset.KVRWSet, error) {\n\trws := &kvrwset.KVRWSet{}\n\terr := proto.Unmarshal(bytes, rws)\n\treturn rws, errors.Wrap(err, \"error unmarshalling KVRWSet\")\n}\n\n// UnmarshalHashedRWSet unmarshals bytes to a HashedRWSet\nfunc UnmarshalHashedRWSet(bytes []byte) (*kvrwset.HashedRWSet, error) {\n\thrws := &kvrwset.HashedRWSet{}\n\terr := proto.Unmarshal(bytes, hrws)\n\treturn hrws, errors.Wrap(err, \"error unmarshalling HashedRWSet\")\n}\n\n// UnmarshalSignaturePolicy unmarshals bytes to a SignaturePolicyEnvelope\nfunc UnmarshalSignaturePolicy(bytes []byte) (*common.SignaturePolicyEnvelope, error) {","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/unmarshalers.go#L161-L197","documentation":"UnmarshalTxReadWriteSet wraps proto.Unmarshal failures for rwset.TxReadWriteSet bytes. It means the supplied bytes are not a valid TxReadWriteSet protobuf message. rwsetDifference calls it, so RW-set comparison tooling hits it when one side has corrupted or wrongly-encoded read-write set bytes.","triggerScenarios":"Calling UnmarshalTxReadWriteSet with nil/empty bytes, bytes of a TxRwSet's internal NsRwSets, an already-unmarshalled struct serialized with json instead of proto, or cross-version proto encodings.","commonSituations":"Comparing RW sets between the simulated ledger and committed transactions, state validation tooling, or tests feeding hand-built byte slices.","solutions":["Ensure the bytes are the marshalled TxReadWriteSet (e.g. proto.Marshal of the whole message), not a sub-message or JSON encoding","Check for empty input before calling; an empty slice will fail to unmarshal","Regenerate the RW set bytes with the same fabric-protos version used for unmarshalling","If unmarshal fails during comparison, treat the sets as differing/invalid rather than retrying"],"exampleFix":"// before\nrws, err := protoutil.UnmarshalTxReadWriteSet(nil)\n// after\nif len(rwsetBytes) == 0 { return errors.New(\"empty rwset bytes\") }\nrws, err := protoutil.UnmarshalTxReadWriteSet(rwsetBytes)","handlingStrategy":"validation","validationCode":"func hasRWSetBytes(b []byte) bool { return len(b) > 0 }","typeGuard":"func safeUnmarshalTxRWS(b []byte) (rws *rwset.TxReadWriteSet, ok bool) {\n    rws, err := protoutil.UnmarshalTxReadWriteSet(b)\n    return rws, err == nil && rws != nil\n}","tryCatchPattern":"rws, err := protoutil.UnmarshalTxReadWriteSet(b)\nif err != nil {\n    return nil, fmt.Errorf(\"rwset comparison aborted, undecodable input: %w\", err)\n}","preventionTips":["Unmarshal only proto.Marshal output of the full TxReadWriteSet","Guard against empty byte slices at comparison boundaries","Do not double-unmarshal already-decoded TxRwSet objects","Keep proto schemas versioned consistently in diff/comparison tools"],"tags":["protobuf","unmarshal","fabric","rwset"],"backgroundTag":"proto-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"}