{"record":{"id":"4eae42140825104c","repo":"hyperledger/fabric","slug":"chaincodespec-s-path-cannot-be-empty-4eae42","errorCode":null,"errorMessage":"ChaincodeSpec's path cannot be empty","messagePattern":"ChaincodeSpec's path cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/platforms/node/platform.go","lineNumber":139,"sourceCode":"\t}\n\n\treturn nil\n}\n\n// Generates a deployment payload by putting source files in src/$file entries in .tar.gz format\nfunc (p *Platform) GetDeploymentPayload(path string) ([]byte, error) {\n\tvar err error\n\n\t// --------------------------------------------------------------------------------------\n\t// Write out our tar package\n\t// --------------------------------------------------------------------------------------\n\tpayload := bytes.NewBuffer(nil)\n\tgw := gzip.NewWriter(payload)\n\ttw := tar.NewWriter(gw)\n\n\tfolder := path\n\tif folder == \"\" {\n\t\treturn nil, errors.New(\"ChaincodeSpec's path cannot be empty\")\n\t}\n\n\t// trim trailing slash if it exists\n\tif folder[len(folder)-1] == '/' {\n\t\tfolder = folder[:len(folder)-1]\n\t}\n\n\tlogger.Debugf(\"Packaging node.js project from path %s\", folder)\n\n\tif err = util.WriteFolderToTarPackage(tw, folder, []string{\"node_modules\"}, nil, nil); err != nil {\n\t\tlogger.Errorf(\"Error writing folder to tar package %s\", err)\n\t\treturn nil, fmt.Errorf(\"Error writing Chaincode package contents: %s\", err)\n\t}\n\n\t// Write the tar file out\n\tif err := tw.Close(); err != nil {\n\t\treturn nil, fmt.Errorf(\"Error writing Chaincode package contents: %s\", err)\n\t}","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/platforms/node/platform.go#L121-L157","documentation":"GetDeploymentPayload builds a tar.gz of the chaincode source from the spec's path. If the path (folder) is empty, there is nothing to package, so the platform returns this error instead of producing a malformed empty payload.","triggerScenarios":"Calling GetDeploymentPayload (directly or via chaincode spec packaging) with ccSpec.Path == \"\" — e.g. an unset ChaincodeSpec path field or a spec constructed programmatically without setting the source path.","commonSituations":"Building a ChaincodeSpec struct and forgetting the Path field, path lost during JSON deserialization, or copying a spec template that left path blank for node chaincode.","solutions":["Set ChaincodeSpec.Path to the chaincode source directory (e.g. 'github.com/example/chaincode/node' or the local path being packaged).","Validate the spec path before calling packaging APIs.","If loading from JSON/config, ensure the path field is populated and non-empty.","Re-run the packaging step after fixing the spec."],"exampleFix":"// before\nspec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_NODE}\n// after\nspec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_NODE, ChaincodeId: &pb.ChaincodeID{Path: \"src/chaincode\"}}","handlingStrategy":"validation","validationCode":"if (!spec.ChaincodeId || !spec.ChaincodeId.Path) {\n  throw new Error('ChaincodeSpec.Path must be set before packaging');\n}","typeGuard":"function hasChaincodePath(spec) {\n  return !!spec && !!spec.ChaincodeId && typeof spec.ChaincodeId.Path === 'string' && spec.ChaincodeId.Path.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always set Path when constructing a ChaincodeSpec","Validate spec fields after JSON deserialization","Use constructors/builders that require the path","Add an assertion before calling packaging APIs"],"tags":["chaincode","packaging","validation","config"],"backgroundTag":"missing-required-path","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"}