{"record":{"id":"277729b260f4e3bc","repo":"hyperledger/fabric","slug":"unexpected-collection-type-277729","errorCode":null,"errorMessage":"unexpected collection type","messagePattern":"unexpected collection type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/privdata/distributor.go","lineNumber":114,"sourceCode":"type CollectionAccessPolicy interface {\n\tprivdata.CollectionAccessPolicy\n}\n\n// policyAccessFactory the implementation of CollectionAccessFactory\ntype policyAccessFactory struct {\n\tIdentityDeserializerFactory\n}\n\nfunc (p *policyAccessFactory) AccessPolicy(config *peer.CollectionConfig, chainID string) (privdata.CollectionAccessPolicy, error) {\n\tcolAP := &privdata.SimpleCollection{}\n\tswitch cconf := config.Payload.(type) {\n\tcase *peer.CollectionConfig_StaticCollectionConfig:\n\t\terr := colAP.Setup(cconf.StaticCollectionConfig, p.GetIdentityDeserializer(chainID))\n\t\tif err != nil {\n\t\t\treturn nil, errors.WithMessagef(err, \"error setting up collection  %#v\", cconf.StaticCollectionConfig.Name)\n\t\t}\n\tdefault:\n\t\treturn nil, errors.New(\"unexpected collection type\")\n\t}\n\treturn colAP, nil\n}\n\n// NewCollectionAccessFactory\nfunc NewCollectionAccessFactory(factory IdentityDeserializerFactory) CollectionAccessFactory {\n\treturn &policyAccessFactory{\n\t\tIdentityDeserializerFactory: factory,\n\t}\n}\n\n// NewDistributor a constructor for private data distributor capable to send\n// private read write sets for underlying collection\nfunc NewDistributor(chainID string, gossip gossipAdapter, factory CollectionAccessFactory,\n\tmetrics *metrics.PrivdataMetrics, pushAckTimeout time.Duration,\n) PvtDataDistributor {\n\treturn &distributorImpl{\n\t\tchainID:                 chainID,","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/privdata/distributor.go#L96-L132","documentation":"The collection access policy factory only understands CollectionConfig_StaticCollectionConfig. When the oneof in peer.CollectionConfig carries any other type (or none), the factory rejects it with 'unexpected collection type'. Static collections are the only supported private-collection kind in this code path.","triggerScenarios":"A collection config package passed to AccessPolicy contains a CollectionConfig whose type field is unset or not StaticCollectionConfig — e.g. a malformed or hand-built collections_config.json, or a proto produced by newer tooling with types this Fabric version doesn't know.","commonSituations":"Hand-edited or generated collections_config.json missing the static_collection_config wrapper; proto field set with the wrong oneof variant; Fabric version mismatch where a config produced by newer tooling is loaded by an older peer.","solutions":["Fix collections_config.json so each entry uses static_collection_config.","Regenerate the collection config with official Fabric tooling for your version.","Ensure the collection config proto's oneof is explicitly set before calling AccessPolicy.","Upgrade peers/tooling so Fabric versions agree on the collection-config schema."],"exampleFix":"// before: malformed collection config (missing static config)\n{\n  \"name\": \"mycollection\"\n}\n\n// after: proper static collection config\n{\n  \"static_collection_config\": {\n    \"name\": \"mycollection\",\n    \"member_orgs_policy\": {\"signature_policy\": {...}},\n    \"required_peer_count\": 3,\n    \"maximum_peer_count\": 3,\n    \"block_to_live\": 0\n  }\n}","handlingStrategy":"validation","validationCode":"for _, c := range collectionConfigs {\n    if c.GetStaticCollectionConfig() == nil {\n        return errors.New(\"only static collection configs are supported\")\n    }\n}","typeGuard":"func isStaticCollectionConfig(cc *peer.CollectionConfig) bool {\n    return cc != nil && cc.GetStaticCollectionConfig() != nil\n}","tryCatchPattern":"colAP, err := factory.AccessPolicy(collectionConfigPackage, chainID)\nif err != nil {\n    if strings.Contains(err.Error(), \"unexpected collection type\") {\n        return errors.New(\"collection config must use static_collection_config; regenerate collections_config.json\")\n    }\n    return err\n}","preventionTips":["Generate collections_config.json with official tooling, never by hand.","Validate the oneof is set (static_collection_config) for every entry.","Keep peer/tooling Fabric versions aligned so proto variants match.","Lint collection packages before chaincode install/upgrade."],"tags":["fabric","collection-config","validation","private-data"],"backgroundTag":"unexpected-collection-type","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"}