{"record":{"id":"5f1d27a5cb73dba6","repo":"hyperledger/fabric","slug":"collection-data-should-not-exist-for-chaincode-s","errorCode":null,"errorMessage":"collection data should not exist for chaincode %s:%s","messagePattern":"collection data should not exist for chaincode (.+?):(.+?)","errorType":"validation","errorClass":"VSCCEndorsementPolicyError","httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":427,"sourceCode":"\n\t// The following condition check added in v1.1 may not be needed as it is not possible to have the chaincodeName~collection key in\n\t// the lscc namespace before a chaincode deploy. To avoid forks in v1.2, the following condition is retained.\n\tif lsccFunc == lscc.DEPLOY {\n\t\tcolCriteria := privdata.CollectionCriteria{Channel: channelName, Namespace: cdRWSet.Name}\n\t\tccp, err := privdata.RetrieveCollectionConfigPackageFromState(colCriteria, state)\n\t\tif err != nil {\n\t\t\t// fail if we get any error other than NoSuchCollectionError\n\t\t\t// because it means something went wrong while looking up the\n\t\t\t// older collection\n\t\t\tif _, ok := err.(privdata.NoSuchCollectionError); !ok {\n\t\t\t\treturn &commonerrors.VSCCExecutionFailureError{\n\t\t\t\t\tErr: fmt.Errorf(\"unable to check whether collection existed earlier for chaincode %s:%s\",\n\t\t\t\t\t\tcdRWSet.Name, cdRWSet.Version),\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ccp != nil {\n\t\t\treturn policyErr(fmt.Errorf(\"collection data should not exist for chaincode %s:%s\", cdRWSet.Name, cdRWSet.Version))\n\t\t}\n\t}\n\n\t// TODO: Once the new chaincode lifecycle is available (FAB-8724), the following validation\n\t// and other validation performed in ValidateLSCCInvocation can be moved to LSCC itself.\n\tnewCollectionConfigPackage := &pb.CollectionConfigPackage{}\n\n\tif collectionsConfigArg != nil {\n\t\terr := proto.Unmarshal(collectionsConfigArg, newCollectionConfigPackage)\n\t\tif err != nil {\n\t\t\treturn policyErr(fmt.Errorf(\"invalid collection configuration supplied for chaincode %s:%s\",\n\t\t\t\tcdRWSet.Name, cdRWSet.Version))\n\t\t}\n\t} else {\n\t\treturn nil\n\t}\n\n\tif ac.V1_2Validation() {","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L409-L445","documentation":"During a collection-aware deploy validation, VSCC checks whether a collection configuration package for the chaincode already exists in the ledger from a previous definition. If one is found (ccp != nil) while validating what appears to be a fresh deploy of collections, the transaction is rejected as a policy error: collections cannot already be deployed on the chaincode at that point.","triggerScenarios":"Redeploying/instantiating a chaincode whose collection config was already written to the ledger by a previous deploy; submitting a duplicate deploy transaction; attempting to instantiate with collections when the '~collection' keys already exist from an earlier instantiation of the same chaincode name.","commonSituations":"Re-running an instantiate command that already succeeded (idempotency mistake); upgrading a chaincode and resubmitting collections config when it should be done through the upgrade path; two operators racing to deploy the same chaincode with collections; scripts retrying a deploy whose first attempt actually committed.","solutions":["Check whether the chaincode/collections are already deployed (peer chaincode list --collections) and skip re-deploying if so.","If you intend to change collections on an existing chaincode, use the chaincode upgrade path rather than re-instantiating.","Make deploy scripts idempotent — query for existing collections before submitting the instantiate transaction.","Coordinate between operators to avoid duplicate deploy submissions for the same chaincode name/version."],"exampleFix":"// before: unconditional re-instantiate\npeer chaincode instantiate -C mychannel -n mycc -v 1.0 -c '{\"Args\":[]}' --collections-config collections.json\n// after: check first\npeer chaincode list --collections --channelID mychannel -n mycc || peer chaincode instantiate -C mychannel -n mycc -v 1.0 -c '{\"Args\":[]}' --collections-config collections.json","handlingStrategy":"validation","validationCode":"// Before deploying, check whether collections already exist on the chaincode\n// peer chaincode list --collections --channelID mychannel -n mycc\n// If any collections are returned, use upgrade instead of instantiate.\nfunc shouldDeploy(existingCollectionsJSON []byte) bool {\n  var ccp map[string]interface{}\n  if json.Unmarshal(existingCollectionsJSON, &ccp) == nil && len(ccp) > 0 {\n    return false // collections already deployed — skip deploy\n  }\n  return true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run 'peer chaincode list --collections' before an instantiate to confirm no prior config exists","Make deploy automation idempotent: query-then-deploy rather than blind submit","Route collection changes on deployed chaincodes through the upgrade path","Coordinate with other operators or use a deployment lock to avoid duplicate deploys"],"tags":["fabric","vscc","collections","deploy","validation"],"backgroundTag":"collection-already-exists","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"}