{"record":{"id":"ce16c00a98791b04","repo":"hyperledger/fabric","slug":"no-chaincode-interests-given","errorCode":null,"errorMessage":"no chaincode interests given","messagePattern":"no chaincode interests given","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/client/client.go","lineNumber":605,"sourceCode":"}\n\nfunc validateStateInfoMessage(message *gprotoext.SignedGossipMessage) error {\n\tsi := message.GetStateInfo()\n\tif si == nil {\n\t\treturn errors.New(\"message isn't a stateInfo message\")\n\t}\n\tif si.Timestamp == nil {\n\t\treturn errors.New(\"timestamp is nil\")\n\t}\n\tif si.Properties == nil {\n\t\treturn errors.New(\"properties is nil\")\n\t}\n\treturn nil\n}\n\nfunc validateInterests(interests ...*peer.ChaincodeInterest) error {\n\tif len(interests) == 0 {\n\t\treturn errors.New(\"no chaincode interests given\")\n\t}\n\tfor _, interest := range interests {\n\t\tif interest == nil {\n\t\t\treturn errors.New(\"chaincode interest is nil\")\n\t\t}\n\t\tif err := InvocationChain(interest.Chaincodes).ValidateInvocationChain(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// InvocationChain aggregates ChaincodeCalls\ntype InvocationChain []*peer.ChaincodeCall\n\n// String returns a string representation of this invocation chain\nfunc (ic InvocationChain) String() string {\n\ts, _ := json.Marshal(ic)","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/client/client.go#L587-L623","documentation":"validateInterests is called when building an endorsers query (AddEndorsersQuery). If the caller supplies zero ChaincodeInterest objects, there is nothing for discovery to resolve, so the client rejects the request before sending it to the service.","triggerScenarios":"Calling discovery.NewEndorsersQuery() with no arguments, or client.AddEndorsersQuery() (via Query) with an empty interests slice.","commonSituations":"Programmatically building an invocation chain from user input where the chaincodes list ended up empty; a code path that skips adding interests when no chaincode was selected.","solutions":["Pass at least one ChaincodeInterest built from ChaincodeInterest{Chaincodes: []*peer.ChaincodeCall{...}}","Verify the chaincode name/collection list used to build the interest is non-empty before calling","Guard the call site: if len(interests) == 0, return an application-level error before invoking discovery"],"exampleFix":"// before\nreq := discovery.NewEndorsersQuery() // empty\nresp, err := client.Send(ctx, req) // error: no chaincode interests given\n// after\ninterest := discovery.ChaincodeInterest{Chaincodes: []*peer.ChaincodeCall{\n    {Name: \"mycc\", CollectionNames: []string{\"col1\"}},\n}}\nreq := discovery.NewEndorsersQuery(interest)\nresp, err := client.Send(ctx, req)","handlingStrategy":"validation","validationCode":"func ensureInterests(interests ...*peer.ChaincodeInterest) error {\n    if len(interests) == 0 {\n        return errors.New(\"at least one ChaincodeInterest is required for endorsers query\")\n    }\n    return nil\n}","typeGuard":"func hasInterests(interests []*peer.ChaincodeInterest) bool { return len(interests) > 0 }","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"no chaincode interests given\") {\n    return fmt.Errorf(\"client bug: endorsers query built without interests: %w\", err)\n}","preventionTips":["Always construct ChaincodeInterest from a non-empty chaincode list","Assert interest count before NewEndorsersQuery","Fail fast in app code when no chaincode was selected"],"tags":["hyperledger-fabric","discovery-service","chaincode","validation","api-misuse"],"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"}