{"record":{"id":"ac54b62e7e0ea851","repo":"hyperledger/fabric","slug":"nil-data-bytes","errorCode":null,"errorMessage":"nil data bytes","messagePattern":"nil data bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/common/ccprovider/cdspackage.go","lineNumber":244,"sourceCode":"func (ccpack *CDSPackage) PutChaincodeToFS() error {\n\tif ccpack.buf == nil {\n\t\treturn errors.New(\"uninitialized package\")\n\t}\n\n\tif ccpack.id == nil {\n\t\treturn errors.New(\"id cannot be nil if buf is not nil\")\n\t}\n\n\tif ccpack.depSpec == nil {\n\t\treturn errors.New(\"depspec cannot be nil if buf is not nil\")\n\t}\n\n\tif ccpack.data == nil {\n\t\treturn errors.New(\"nil data\")\n\t}\n\n\tif ccpack.datab == nil {\n\t\treturn errors.New(\"nil data bytes\")\n\t}\n\n\tccname := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Name\n\tccversion := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Version\n\n\t// return error if chaincode exists\n\tpath := fmt.Sprintf(\"%s/%s.%s\", chaincodeInstallPath, ccname, ccversion)\n\tif _, err := os.Stat(path); err == nil {\n\t\treturn fmt.Errorf(\"chaincode %s exists\", path)\n\t}\n\n\tif err := os.WriteFile(path, ccpack.buf, 0o644); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/common/ccprovider/cdspackage.go#L226-L262","documentation":"ccpack.datab is the serialized bytes of the ChaincodeData (data marshaled to protobuf). PutChaincodeToFS checks it last before writing: buf/id/depSpec/data all present but datab nil means the final marshal step never ran, so the on-disk package would be incomplete and the write is refused.","triggerScenarios":"A CDSPackage populated through custom code that set data but never serialized it to datab (proto.Marshal step in InitFromBuffer/PutChaincodeDepSpec skipped or its error ignored).","commonSituations":"Reimplementing package initialization in forked code and missing the datab = proto.Marshal(data) step; a marshal failure swallowed earlier; deep-copying a package and dropping the bytes field; test fixtures missing one field.","solutions":["Initialize via InitFromBuffer/InitFromPath, which marshal ChaincodeData into datab, then call PutChaincodeToFS.","If manual, marshal the data yourself: datab, err := proto.Marshal(ccpack.data); check err and assign ccpack.datab before writing.","Stop hand-assembling CDSPackage and route through ccprovider.PutChaincode / processCDS which guarantee full population."],"exampleFix":"// before\nccpack.data = ccdata // datab never marshaled\nccpack.PutChaincodeToFS()\n\n// after\ndatab, err := proto.Marshal(ccdata)\nif err != nil {\n    return err\n}\nccpack.datab = datab\nccpack.PutChaincodeToFS()","handlingStrategy":"validation","validationCode":"if ccpack.buf != nil && ccpack.datab == nil {\n    return errors.New(\"ChaincodeData bytes missing: data must be marshaled before PutChaincodeToFS\")\n}","typeGuard":"func hasDataBytes(p *ccprovider.CDSPackage) bool {\n    return p != nil && p.buf != nil && p.datab != nil\n}","tryCatchPattern":"if err := ccpack.PutChaincodeToFS(); err != nil {\n    if err.Error() == \"nil data bytes\" {\n        return fmt.Errorf(\"package serialization incomplete: %w\", err)\n    }\n    return err\n}","preventionTips":["Use the library's init functions so the proto.Marshal(data) -> datab step is never skipped.","When deep-copying packages, ensure byte slices (buf, datab) are carried over or regenerated.","Verify package completeness (buf, id, depSpec, data, datab all non-nil) before any write path."],"tags":["hyperledger-fabric","chaincode","go","nil-field"],"backgroundTag":"nil-field-invariant-violation","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"}