{"record":{"id":"10b8c6236b2bae23","repo":"hyperledger/fabric","slug":"chaincode-name-in-interest-cannot-be-empty","errorCode":null,"errorMessage":"chaincode name in interest cannot be empty","messagePattern":"chaincode name in interest cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/service.go","lineNumber":275,"sourceCode":"\t\treturn nil, errors.New(\"client claimed TLS hash doesn't match computed TLS hash from gRPC stream\")\n\t}\n\treturn req, nil\n}\n\nfunc validateCCQuery(ccQuery *discovery.ChaincodeQuery) error {\n\tif len(ccQuery.Interests) == 0 {\n\t\treturn errors.New(\"chaincode query must have at least one chaincode interest\")\n\t}\n\tfor _, interest := range ccQuery.Interests {\n\t\tif interest == nil {\n\t\t\treturn errors.New(\"chaincode interest is nil\")\n\t\t}\n\t\tif len(interest.Chaincodes) == 0 {\n\t\t\treturn errors.New(\"chaincode interest must contain at least one chaincode\")\n\t\t}\n\t\tfor _, cc := range interest.Chaincodes {\n\t\t\tif cc.Name == \"\" {\n\t\t\t\treturn errors.New(\"chaincode name in interest cannot be empty\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc wrapError(err error) *discovery.QueryResult {\n\treturn &discovery.QueryResult{\n\t\tResult: &discovery.QueryResult_Error{\n\t\t\tError: &discovery.Error{\n\t\t\t\tContent: err.Error(),\n\t\t\t},\n\t\t},\n\t}\n}\n","sourceCodeStart":257,"sourceCodeEnd":291,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/service.go#L257-L291","documentation":"A chaincode entry inside a discovery ChaincodeInterest has an empty Name field. The discovery service requires every chaincode call it validates to identify the chaincode by name; an unnamed entry cannot be mapped to endorsers, so validation fails.","triggerScenarios":"Constructing discovery.ChaincodeCall without setting Name (e.g. only setting CollectionNames or NoPrivateReads), or populating names from an empty config/env variable.","commonSituations":"Private-data collection queries where the developer set CollectionNames but left Name blank; templated request builders where the chaincode name placeholder was never substituted; typos in YAML/JSON config keys for the chaincode name.","solutions":["Set the Name field on every ChaincodeCall in the interest to the chaincode instantiated on the channel","Check the config/source of the chaincode name — an empty env var or config key is being read","Filter out ChaincodeCall entries with empty Name before building the query"],"exampleFix":"// before\ncall := &discovery.ChaincodeCall{CollectionNames: []string{\"col1\"}}\n// after\ncall := &discovery.ChaincodeCall{Name: \"mycc\", CollectionNames: []string{\"col1\"}}","handlingStrategy":"validation","validationCode":"for _, interest := range ccQuery.Interests {\n    for _, cc := range interest.Chaincodes {\n        if cc.Name == \"\" {\n            return errors.New(\"chaincode name required\")\n        }\n    }\n}","typeGuard":"func validChaincodeCall(cc *discovery.ChaincodeCall) bool {\n    return cc != nil && cc.Name != \"\"\n}","tryCatchPattern":"res, err := client.Send(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"name in interest cannot be empty\") {\n        // inspect request chaincode names before resending\n    }\n    return err\n}","preventionTips":["Validate that env/config values substituted into ChaincodeCall.Name are non-empty","Fail fast at request-construction time, not at discovery time","Keep collection queries paired with an explicit chaincode Name"],"tags":["fabric","discovery","validation","chaincode"],"backgroundTag":"missing-required-argument","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"}