{"record":{"id":"a91b6e712d58e54b","repo":"hyperledger/fabric","slug":"empty-chaincode-name-in-chaincode-id","errorCode":null,"errorMessage":"empty chaincode name in chaincode id","messagePattern":"empty chaincode name in chaincode id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tx/endorser/parser.go","lineNumber":153,"sourceCode":"\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)\nfunc UnmarshalEndorserTxAndValidate(txenv *tx.Envelope) (*EndorserTx, error) {\n\tetx, err := unmarshalEndorserTx(txenv)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/tx/endorser/parser.go#L135-L171","documentation":"Thrown by the endorser parser's validate() when the ChaincodeID is present but its Name field is an empty string. A chaincode name is the minimum required routing key for a transaction; the library rejects anonymous chaincode invocations. Note ChaincodeID with only a Path/Version but no Name also triggers this.","triggerScenarios":"Creating a ChaincodeSpec with ChaincodeId set to &pb.ChaincodeID{} or with only Version/Path populated, then submitting the proposal through validation.","commonSituations":"Dynamic chaincode name variables that resolved to empty string due to config/env lookup failures; typos in struct field initialization; test fixtures omitting Name.","solutions":["Ensure ChaincodeID.Name is set to the deployed chaincode's name before building the proposal.","Validate the chaincode name source (config key, flag) is non-empty at startup.","Fail fast in client code: if ccName == \"\" { return fmt.Errorf(\"chaincode name required\") }."],"exampleFix":"// before\nccid := &pb.ChaincodeID{Version: \"1.0\"}\n// after\nccid := &pb.ChaincodeID{Name: \"mycc\", Version: \"1.0\"}","handlingStrategy":"validation","validationCode":"if spec.ChaincodeId == nil || spec.ChaincodeId.Name == \"\" { return errors.New(\"chaincode name required\") }","typeGuard":"func hasChaincodeName(spec *pb.ChaincodeSpec) bool { return spec != nil && spec.ChaincodeId != nil && spec.ChaincodeId.Name != \"\" }","tryCatchPattern":null,"preventionTips":["Source chaincode names from checked config with a required-field check at startup.","Fail fast on empty name variables rather than passing them downstream.","Centralize chaincode name constants instead of ad-hoc strings."],"tags":["fabric","transaction-validation","chaincode"],"backgroundTag":"missing-chaincode-name","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"}