{"record":{"id":"b53e8bec31621209","repo":"hyperledger/fabric","slug":"chaincode-id-is-nil","errorCode":null,"errorMessage":"chaincode id is nil","messagePattern":"chaincode id is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/proputils.go","lineNumber":435,"sourceCode":"\n\tproposalPayload := &peer.ChaincodeProposalPayload{}\n\terr = proto.Unmarshal(proposal.Payload, proposalPayload)\n\tif err != nil {\n\t\treturn \"\", errors.WithMessage(err, \"could not unmarshal chaincode proposal payload\")\n\t}\n\n\tcis := &peer.ChaincodeInvocationSpec{}\n\terr = proto.Unmarshal(proposalPayload.Input, cis)\n\tif err != nil {\n\t\treturn \"\", errors.WithMessage(err, \"could not unmarshal chaincode invocation spec\")\n\t}\n\n\tif cis.ChaincodeSpec == nil {\n\t\treturn \"\", errors.Errorf(\"chaincode spec is nil\")\n\t}\n\n\tif cis.ChaincodeSpec.ChaincodeId == nil {\n\t\treturn \"\", errors.Errorf(\"chaincode id is nil\")\n\t}\n\n\treturn cis.ChaincodeSpec.ChaincodeId.Name, nil\n}\n","sourceCodeStart":417,"sourceCodeEnd":440,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/proputils.go#L417-L440","documentation":"After confirming ChaincodeSpec is non-nil, InvokedChaincodeName also requires ChaincodeSpec.ChaincodeId to be set, since the chaincode name is read from ChaincodeId.Name. A spec without a ChaincodeId cannot name the target chaincode, so this error is returned.","triggerScenarios":"A ChaincodeInvocationSpec whose ChaincodeSpec exists but has a nil ChaincodeId reaches InvokedChaincodeName — proposals built with only Type/Input set, or specs deserialized from bytes missing the chaincode_id field.","commonSituations":"Hand-built proposals missing the ChaincodeID; older/other-version SDKs emitting specs where the id field was dropped; SystemCC or constructor paths that set input args without a chaincode id.","solutions":["Set ChaincodeSpec.ChaincodeId (at minimum the Name field) when constructing the ChaincodeInvocationSpec.","Ensure the proposal builder in your client passes the chaincode name (and version/path where applicable) into the ChaincodeID.","For on-chain proposals received from peers, reject malformed ones and require the submitting client to resend a correctly built proposal.","When converting from legacy formats, map old spec fields into the new ChaincodeID explicitly instead of relying on defaults."],"exampleFix":"// before\ncs := &peer.ChaincodeSpec{Type: peer.ChaincodeSpec_GOLANG, Input: ci}\n\n// after\ncs := &peer.ChaincodeSpec{\n    Type:        peer.ChaincodeSpec_GOLANG,\n    ChaincodeId: &peer.ChaincodeID{Name: \"mycc\", Version: \"v1\"},\n    Input:       ci,\n}","handlingStrategy":"validation","validationCode":"if cis.ChaincodeSpec == nil || cis.ChaincodeSpec.ChaincodeId == nil || cis.ChaincodeSpec.ChaincodeId.Name == \"\" {\n    return errors.New(\"invoke proposal must carry a chaincode id with a name\")\n}","typeGuard":"func hasChaincodeID(cs *peer.ChaincodeSpec) bool {\n    return cs != nil && cs.ChaincodeId != nil && cs.ChaincodeId.Name != \"\"\n}","tryCatchPattern":"name, err := protoutil.InvokedChaincodeName(signedProp)\nif err != nil {\n    httpStatus = codes.InvalidArgument\n    return fmt.Errorf(\"proposal missing chaincode id: %w\", err)\n}","preventionTips":["Always set peer.ChaincodeID{Name: ...} when building a ChaincodeSpec.","For system chaincode calls, set the well-known system CC name explicitly.","Validate proposals client-side (name non-empty) before signing.","When migrating from legacy proposal formats, map the chaincode id field explicitly."],"tags":["fabric","proposal","chaincode-id","malformed-payload"],"backgroundTag":"nil-chaincode-spec","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"}