{"record":{"id":"305c50ddcd0e9888","repo":"hyperledger/fabric","slug":"error-marshaling-chaincodeevent-proto-marshal-ca","errorCode":null,"errorMessage":"error marshaling ChaincodeEvent: proto: Marshal called with nil","messagePattern":"error marshaling ChaincodeEvent: proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/proputils.go","lineNumber":155,"sourceCode":"\t\treturn nil, errors.New(\"error marshaling ChaincodeProposalPayload: proto: Marshal called with nil\")\n\t}\n\tcppBytes, err := proto.Marshal(cpp)\n\treturn cppBytes, errors.Wrap(err, \"error marshaling ChaincodeProposalPayload\")\n}\n\n// GetBytesResponse gets the bytes of Response\nfunc GetBytesResponse(res *peer.Response) ([]byte, error) {\n\tif res == nil {\n\t\treturn nil, errors.New(\"error marshaling Response: proto: Marshal called with nil\")\n\t}\n\tresBytes, err := proto.Marshal(res)\n\treturn resBytes, errors.Wrap(err, \"error marshaling Response\")\n}\n\n// GetBytesChaincodeEvent gets the bytes of ChaincodeEvent\nfunc GetBytesChaincodeEvent(event *peer.ChaincodeEvent) ([]byte, error) {\n\tif event == nil {\n\t\treturn nil, errors.New(\"error marshaling ChaincodeEvent: proto: Marshal called with nil\")\n\t}\n\teventBytes, err := proto.Marshal(event)\n\treturn eventBytes, errors.Wrap(err, \"error marshaling ChaincodeEvent\")\n}\n\n// GetBytesChaincodeActionPayload get the bytes of ChaincodeActionPayload from\n// the message\nfunc GetBytesChaincodeActionPayload(cap *peer.ChaincodeActionPayload) ([]byte, error) {\n\tif cap == nil {\n\t\treturn nil, errors.New(\"error marshaling ChaincodeActionPayload: proto: Marshal called with nil\")\n\t}\n\tcapBytes, err := proto.Marshal(cap)\n\treturn capBytes, errors.Wrap(err, \"error marshaling ChaincodeActionPayload\")\n}\n\n// GetBytesProposalResponse gets proposal bytes response\nfunc GetBytesProposalResponse(pr *peer.ProposalResponse) ([]byte, error) {\n\tif pr == nil {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/proputils.go#L137-L173","documentation":"GetBytesChaincodeEvent serializes a *peer.ChaincodeEvent. When the passed pointer is nil, proto.Marshal cannot operate on it, so the function short-circuits and returns this explicit 'proto: Marshal called with nil' error. It exists to convert an otherwise opaque panic/failure into a clear message naming the offending message type.","triggerScenarios":"Calling protoutil.GetBytesChaincodeEvent(nil), or passing an event field from a transaction/chaincode action where the event was absent (e.g. ccEvent not extracted from ChaincodeAction).","commonSituations":"Chaincode executed without firing an event but the listener code unconditionally serializes the event; parsing block events where some transactions legitimately carry no ChaincodeEvent.","solutions":["Nil-check the *peer.ChaincodeEvent before serialization and skip/return early when absent.","In event-processing loops, treat nil events as 'no event emitted' rather than an error path.","Ensure chaincode stub SetEvent was called if an event is expected.","In tests, construct &peer.ChaincodeEvent{...} with required fields before calling."],"exampleFix":"// before\nevBytes, err := protoutil.GetBytesChaincodeEvent(evt)\n// after\nif evt == nil {\n    return nil // no event emitted for this transaction\n}\nevBytes, err := protoutil.GetBytesChaincodeEvent(evt)","handlingStrategy":"type-guard","validationCode":"if evt == nil {\n    return nil // no ChaincodeEvent emitted; skip serialization\n}","typeGuard":"func hasChaincodeAction(ca *peer.ChaincodeAction) bool {\n    return ca != nil\n}\nfunc hasEvent(tx *protoutil.TxMetadata) bool { /* check extracted event non-nil */ return false }","tryCatchPattern":"evBytes, err := protoutil.GetBytesChaincodeEvent(evt)\nif err != nil {\n    return errors.Wrap(err, \"ChaincodeEvent serialization failed\")\n}","preventionTips":["Treat nil ChaincodeEvent as 'no event' in block/tx event processing loops.","Only call SetEvent/emit logic when an event is required by the chaincode contract.","Extract the event via protoutil helpers and check for nil before use."],"tags":["grpc","protobuf","nil-pointer","chaincode-events","hyperledger-fabric"],"backgroundTag":"proto-marshal-nil-message","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"}