{"record":{"id":"98bc64c8a7f0686b","repo":"hyperledger/fabric","slug":"policy-of-s-is-nil","errorCode":null,"errorMessage":"policy of %s is nil","messagePattern":"policy of (.+?) is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/endorsement/collection.go","lineNumber":33,"sourceCode":"\nfunc principalsFromCollectionConfig(ccp *peer.CollectionConfigPackage) (principalSetsByCollectionName, error) {\n\tprincipalSetsByCollections := make(principalSetsByCollectionName)\n\tif ccp == nil {\n\t\treturn principalSetsByCollections, nil\n\t}\n\tfor _, colConfig := range ccp.Config {\n\t\tstaticCol := colConfig.GetStaticCollectionConfig()\n\t\tif staticCol == nil {\n\t\t\t// Right now we only support static collections, so if we got something else\n\t\t\t// we should refuse to process further\n\t\t\treturn nil, errors.Errorf(\"expected a static collection but got %v instead\", colConfig)\n\t\t}\n\t\tif staticCol.MemberOrgsPolicy == nil {\n\t\t\treturn nil, errors.Errorf(\"MemberOrgsPolicy of %s is nil\", staticCol.Name)\n\t\t}\n\t\tpol := staticCol.MemberOrgsPolicy.GetSignaturePolicy()\n\t\tif pol == nil {\n\t\t\treturn nil, errors.Errorf(\"policy of %s is nil\", staticCol.Name)\n\t\t}\n\t\tvar principals policies.PrincipalSet\n\t\t// We now extract all principals from the policy\n\t\tfor _, principal := range pol.Identities {\n\t\t\tprincipals = append(principals, principal)\n\t\t}\n\t\tprincipalSetsByCollections[staticCol.Name] = principals\n\t}\n\treturn principalSetsByCollections, nil\n}\n\ntype principalSetsByCollectionName map[string]policies.PrincipalSet\n\n// toIdentityFilter converts this principalSetsByCollectionName mapping to a filter\n// which accepts or rejects identities of peers.\nfunc (psbc principalSetsByCollectionName) toIdentityFilter(channel string, evaluator principalEvaluator, cc *peer.ChaincodeCall) (identityFilter, error) {\n\tvar principalSets policies.PrincipalSets\n\tfor _, col := range cc.CollectionNames {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/endorsement/collection.go#L15-L51","documentation":"After confirming MemberOrgsPolicy exists, discovery extracts principals from its signature policy. If the policy is present but is not a signature policy (GetSignaturePolicy returns nil), discovery cannot enumerate the endorsing organizations and returns this error for the named collection.","triggerScenarios":"A collection whose MemberOrgsPolicy uses a non-signature policy type (or is an empty wrapper) is processed during PeersForEndorsement principal computation.","commonSituations":"Collection configs generated by tooling that emits an empty memberOrgsPolicy object; manually edited collection JSON where the signaturePolicy body was removed; version skew between config producers and discovery service.","solutions":["Ensure memberOrgsPolicy.signaturePolicy with a valid identities array exists in the collection config","Redeploy/upgrade the chaincode definition with a corrected collections file","Validate collection JSON against the Fabric schema before chaincode approval"],"exampleFix":"// before\n\"memberOrgsPolicy\": {}\n\n// after\n\"memberOrgsPolicy\": {\"signaturePolicy\": {\"identities\": [{\"role\": {\"name\": \"peer\", \"mspId\": \"Org1MSP\"}}]}}","handlingStrategy":"validation","validationCode":"for _, col := range collConfig.Config {\n    sc := col.GetStaticCollectionConfig()\n    if sc != nil && sc.GetMemberOrgsPolicy() != nil && sc.GetMemberOrgsPolicy().GetSignaturePolicy() == nil {\n        return fmt.Errorf(\"collection %s memberOrgsPolicy has no signature policy\", sc.Name)\n    }\n}","typeGuard":"func hasSignaturePolicy(sc *pb.StaticCollectionConfig) bool {\n    return sc != nil && sc.GetMemberOrgsPolicy() != nil && sc.GetMemberOrgsPolicy().GetSignaturePolicy() != nil\n}","tryCatchPattern":"_, err := coll.PrincipalsFromCollectionConfig(ccp)\nif err != nil {\n    if strings.Contains(err.Error(), \"policy of\") {\n        return nil, fmt.Errorf(\"collection memberOrgsPolicy must be a signature policy: %v\", err)\n    }\n    return nil, err\n}","preventionTips":["Always populate memberOrgsPolicy.signaturePolicy.identities with at least one MSP role","Lint collection JSON files for empty memberOrgsPolicy objects","Test collection configs against a sandbox peer before committing to the channel"],"tags":["discovery","collections","policy"],"backgroundTag":"nil-collection-policy","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"}