{"record":{"id":"1e8b4ae285209573","repo":"hyperledger/fabric","slug":"chaincode-name-should-not-be-empty","errorCode":null,"errorMessage":"chaincode name should not be empty","messagePattern":"chaincode name should not be empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/client/client.go","lineNumber":634,"sourceCode":"}\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)\n\treturn string(s)\n}\n\n// ValidateInvocationChain validates the InvocationChain's structure\nfunc (ic InvocationChain) ValidateInvocationChain() error {\n\tif len(ic) == 0 {\n\t\treturn errors.New(\"invocation chain should not be empty\")\n\t}\n\tfor _, cc := range ic {\n\t\tif cc.Name == \"\" {\n\t\t\treturn errors.New(\"chaincode name should not be empty\")\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":616,"sourceCodeEnd":639,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/client/client.go#L616-L639","documentation":"ValidateInvocationChain iterates over the chain's chaincode entries and requires each one to have a non-empty Name. A ChaincodeCall with an empty Name cannot be resolved to a chaincode by the discovery service, so the library rejects it before a request is sent. This protects against partially initialized ChaincodeCall structs.","triggerScenarios":"Calling ValidateInvocationChain() when the InvocationChain contains an entry whose Name field is \"\" — e.g. `discovery.InvocationChain{{Name: \"\"}}` or a ChaincodeCall built from an unset variable.","commonSituations":"Populating chaincode names from CLI flags, env vars, or config that were left blank; JSON/config unmarshalling that left Name zero-valued; typo'd struct field assignment.","solutions":["Ensure every chaincode entry has a Name set before validating","Validate the config/flag sourcing the chaincode name (reject empty strings early)","Print/log the chain contents to find the entry with the missing name"],"exampleFix":"// before\nchain := discovery.InvocationChain{{Name: ccName}} // ccName == \"\"\n// after\nif ccName == \"\" {\n    return errors.New(\"chaincode name required\")\n}\nchain := discovery.InvocationChain{{Name: ccName}}","handlingStrategy":"validation","validationCode":"for i, cc := range chain {\n    if cc.Name == \"\" {\n        return fmt.Errorf(\"invocation chain entry %d has no chaincode name\", i)\n    }\n}","typeGuard":"func namedChaincodes(chain discovery.InvocationChain) bool {\n    for _, cc := range chain {\n        if cc.Name == \"\" {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":"if err := chain.ValidateInvocationChain(); err != nil {\n    if strings.Contains(err.Error(), \"name should not be empty\") {\n        log.Printf(\"check chaincode name inputs: %v\", err)\n    }\n    return err\n}","preventionTips":["Reject empty chaincode-name flags/config values at startup","Default chaincode names in one place rather than scattered call sites","Add a smoke test that validates the assembled chain"],"tags":["go","discovery","validation","input-validation"],"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"}