{"record":{"id":"d5149adeab642155","repo":"hyperledger/fabric","slug":"nil-chaincodeid","errorCode":null,"errorMessage":"nil ChaincodeId","messagePattern":"nil ChaincodeId","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tx/endorser/parser.go","lineNumber":149,"sourceCode":"\n\tif e.Version != 0 {\n\t\treturn errors.Errorf(\"invalid version in ChannelHeader. Expected 0, got [%d]\", e.Version)\n\t}\n\n\tif err := ValidateChannelID(e.ChannelID); err != nil {\n\t\treturn err\n\t}\n\n\tif len(e.Nonce) == 0 {\n\t\treturn errors.New(\"empty nonce\")\n\t}\n\n\tif len(e.Creator) == 0 {\n\t\treturn errors.New(\"empty creator\")\n\t}\n\n\tif e.ChaincodeID == nil {\n\t\treturn errors.New(\"nil ChaincodeId\")\n\t}\n\n\tif e.ChaincodeID.Name == \"\" {\n\t\treturn errors.New(\"empty chaincode name in chaincode id\")\n\t}\n\n\t// TODO FAB-16170: check proposal hash\n\n\t// TODO FAB-16170: verify that txid matches the one in the header\n\n\t// TODO FAB-16170: check that header in the tx action and channel header match bitwise\n\n\treturn nil\n}\n\n// UnmarshalEndorserTxAndValidate receives a tx.Envelope containing\n// a partially unmarshalled endorser transaction and returns an EndorserTx\n// instance (or an error)","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/tx/endorser/parser.go#L131-L167","documentation":"Thrown by the endorser parser's validate() when ChaincodeID is nil while the ChaincodeID field of the ChaincodeInvocationSpec/Proposal is required. The parser needs at least a chaincode name to route and validate the transaction. A nil ChaincodeID means the proposal does not identify the target chaincode, so validation fails.","triggerScenarios":"Submitting a chaincode proposal whose ChaincodeInvocationSpec.ChaincodeSpec.ChaincodeId is unset — e.g. constructing a ChaincodeSpec with only Type/Name missing the ChaincodeID field, or invoking a query built by hand without the ccid.","commonSituations":"Hand-crafted protobuf proposals in tests; SDK upgrades where ChaincodeSpec construction changed; invoking system chaincodes with partially populated specs; copying proposal templates and forgetting the Id field.","solutions":["Populate ChaincodeSpec.ChaincodeId with &pb.ChaincodeID{Name: <ccname>} (and Version/Path if needed) before building the proposal.","Use the SDK's proposal builder which fills ChaincodeID from the invoke arguments instead of manual protobuf assembly.","Guard before submit: if spec.ChaincodeId == nil { return error }."],"exampleFix":"// before\nspec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: nil}\n// after\nspec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: \"mycc\"}}","handlingStrategy":"validation","validationCode":"if spec.ChaincodeId == nil { return errors.New(\"ChaincodeSpec.ChaincodeId must be set\") }","typeGuard":"func hasChaincodeID(spec *pb.ChaincodeSpec) bool { return spec != nil && spec.ChaincodeId != nil }","tryCatchPattern":null,"preventionTips":["Construct ChaincodeSpec with a named ChaincodeID in one helper used everywhere.","Never initialize ChaincodeID structs as bare empty literals.","Validate the full spec (Type, ChaincodeId.Name, Input) before proposal creation."],"tags":["fabric","transaction-validation","chaincode"],"backgroundTag":"nil-chaincode-id","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"}