{"record":{"id":"5c9352e04ab8eb3c","repo":"theonedev/onedev","slug":"chart-archive-not-found","errorCode":null,"errorMessage":"Chart archive not found","messagePattern":"Chart archive not found","errorType":"http","errorClass":"ClientException","httpStatus":400,"severity":"error","filePath":"server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java","lineNumber":172,"sourceCode":"                checkProject(projectId, true);\n            });\n            var baos = new ByteArrayOutputStream();\n            var contentType = request.getHeader(\"Content-Type\");\n            if (contentType != null && (contentType.contains(\"multipart/form-data\") || contentType.contains(\"application/x-www-form-urlencoded\"))) {\n                try {\n                    var upload = new ServletFileUpload();\n                    var items = upload.getItemIterator(request);\n                    if (items.hasNext()) {\n                        var item = items.next();\n                        try (var is = item.openStream()) {\n                            var copied = IOUtils.copyWithMaxSize(is, baos, MAX_FILE_SIZE);\n                            if (copied == -1)\n                                throw new ClientException(SC_NOT_ACCEPTABLE, \"Chart archive exceeds maximum size: \" + MAX_FILE_SIZE);\n                        } catch (IOException e) {\n                            throw new RuntimeException(e);\n                        }\n                    } else {\n                        throw new ClientException(SC_BAD_REQUEST, \"Chart archive not found\");\n                    }\n                } catch (FileUploadException|IOException e) {\n                    throw new RuntimeException(e);\n                }\n            } else {\n                try (var is = request.getInputStream()) {\n                    var copied = IOUtils.copyWithMaxSize(is, baos, MAX_FILE_SIZE);\n                    if (copied == -1)\n                        throw new ClientException(SC_NOT_ACCEPTABLE, \"Chart archive exceeds maximum size: \" + MAX_FILE_SIZE);\n                } catch (IOException e) {\n                    throw new RuntimeException(e);\n                }    \n            }\n            Map<String, Object> metadata = null;\n            var bytes = baos.toByteArray();\n\n            try (var is = new TarInputStream(new GZIPInputStream(new ByteArrayInputStream(bytes)))) {\n                TarEntry entry;","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java#L154-L190","documentation":"HelmPackHandler throws this ClientException (HTTP 400) when a multipart request contains no upload item at all — items.hasNext() is false on the first iteration. The handler expects exactly one file part holding the chart .tgz; without it there is nothing to process.","triggerScenarios":"POST to the helm publish endpoint with multipart content type but zero file parts, or with only non-file form fields.","commonSituations":"Custom scripts/CI calling the REST endpoint without attaching the chart file (wrong form field name or file omitted); HTTP client sending Content-Type: multipart/form-data with an empty body; proxy stripping the request body.","solutions":["Attach the chart archive as the first file part of the multipart request (e.g. curl -F \"chart@mychart-0.1.0.tgz\").","Use helm push or the official OneDev client instead of hand-rolled requests.","Check that the HTTP client actually reads the file (non-empty path) before sending.","Inspect request logs/proxy to confirm the body is not stripped (Content-Length > 0)."],"exampleFix":"// before (no file attached)\ncurl -X POST -H \"Content-Type: multipart/form-data\" https://onedev/~project/helm\n// after\ncurl -X POST -F \"chart@mychart-0.1.0.tgz\" https://onedev/~project/helm","handlingStrategy":"validation","validationCode":"# verify the file exists and is non-empty before upload\n[ -s mychart-0.1.0.tgz ] || { echo 'chart archive missing'; exit 1; }\n# then attach it explicitly\ncurl -f -X POST -F \"chart@mychart-0.1.0.tgz\" https://onedev/~project/helm","typeGuard":null,"tryCatchPattern":"try {\n    uploadChart(path);\n} catch (ClientException e) {\n    if (String(e).contains('Chart archive not found')) throw new IllegalStateException(\"Multipart body must include the chart file part\", e);\n    throw e;\n}","preventionTips":["Use `helm push` or the documented client rather than hand-rolled HTTP.","Assert file existence and non-zero size in CI before the upload step.","Verify Content-Length > 0 at proxy level for upload endpoints."],"tags":["helm","upload","http","missing-file"],"backgroundTag":"missing-required-argument","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}