{"record":{"id":"48066bd527969d2b","repo":"hyperledger/fabric","slug":"only-applicable-for-private-data","errorCode":null,"errorMessage":"only applicable for private data","messagePattern":"only applicable for private data","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/handler.go","lineNumber":1262,"sourceCode":"\n\tif err := h.purgePrivateData(delState, txContext, msg.ChannelId); err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\t// Send response msg back to chaincode.\n\treturn &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil\n}\n\nfunc (h *Handler) purgePrivateData(msg *pb.DelState, txContext *TransactionContext, channelId string) error {\n\terr := h.checkPurgePrivateDataCap(channelId)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnamespaceID := txContext.NamespaceID\n\tcollection := msg.Collection\n\tif collection == \"\" {\n\t\treturn errors.New(\"only applicable for private data\")\n\t}\n\n\tif txContext.IsInitTransaction {\n\t\treturn errors.New(\"private data APIs are not allowed in chaincode Init()\")\n\t}\n\n\tif err = errorIfCreatorHasNoWritePermission(namespaceID, collection, txContext); err != nil {\n\t\treturn err\n\t}\n\n\tif err = txContext.TXSimulator.PurgePrivateData(namespaceID, collection, msg.Key); err != nil {\n\t\treturn errors.WithStack(err)\n\t}\n\n\treturn nil\n}\n\nfunc (h *Handler) HandleWriteBatch(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {","sourceCodeStart":1244,"sourceCodeEnd":1280,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/handler.go#L1244-L1280","documentation":"This error is returned by the peer's chaincode handler when a chaincode calls a private-data-capable system API (e.g. GetPrivateData, PutPrivateData, GetPrivateDataHash) without specifying a collection name. The collection argument is mandatory because all private data operations are scoped to a specific collection; an empty string means the chaincode invoked the private data API incorrectly. The handler rejects the call before doing any ledger work.","triggerScenarios":"Calling a private data API such as ctx.GetStub().GetPrivateData(...) or PutPrivateData(...) with an empty collection name — e.g. passing an unbound/empty variable or using the public-state API shape on the private-data handler path (GetStateAsBytes-style calls routed through the private data message handler without msg.Collection set).","commonSituations":"Chaincode code that reads the collection name from a key or parameter that is empty at runtime; calling GetPrivateData with args[0] unset in the invoke arguments; copy-paste from public GetState where collection was later added but never populated; mixing up GetState and GetPrivateData signatures.","solutions":["Pass a valid, non-empty collection name defined in the chaincode's collection configuration as the first argument to the private data API","Check the invoke args order: GetPrivateData(collection, key) — ensure the collection is args[0] and was supplied by the client","Verify the client proposal inputs actually include the collection name (log args before the call)"],"exampleFix":"// before\nvalue, err := stub.GetPrivateData(collectionArg, key) // collectionArg == \"\"\n\n// after\nif collectionArg == \"\" {\n\treturn shim.Error(\"collection name must be provided\")\n}\nvalue, err := stub.GetPrivateData(\"collectionOK\", key)","handlingStrategy":"validation","validationCode":"func validatePrivateDataCall(collection string) error {\n\tif collection == \"\" {\n\t\treturn fmt.Errorf(\"collection name required for private data API\")\n\t}\n\treturn nil\n}\n// call before stub.GetPrivateData(collection, key)","typeGuard":null,"tryCatchPattern":"resp, err := stub.GetPrivateData(collection, key)\nif err != nil {\n\tif strings.Contains(err.Error(), \"only applicable for private data\") {\n\t\treturn shim.Error(\"empty collection passed to private data API\")\n\t}\n\treturn shim.Error(err.Error())\n}","preventionTips":["Validate collection names at chaincode function entry before any ledger calls","Define collection names as exported constants instead of passing raw args","Log invoke arguments when a private data call fails to spot missing collection inputs"],"tags":["fabric","chaincode","private-data","validation"],"backgroundTag":"missing-private-collection-name","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"}