theonedev/onedev · error · ClientException

Chart archive not found

Error message

Chart archive not found

What it means

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.

Source

Thrown at server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java:172

                checkProject(projectId, true);
            });
            var baos = new ByteArrayOutputStream();
            var contentType = request.getHeader("Content-Type");
            if (contentType != null && (contentType.contains("multipart/form-data") || contentType.contains("application/x-www-form-urlencoded"))) {
                try {
                    var upload = new ServletFileUpload();
                    var items = upload.getItemIterator(request);
                    if (items.hasNext()) {
                        var item = items.next();
                        try (var is = item.openStream()) {
                            var copied = IOUtils.copyWithMaxSize(is, baos, MAX_FILE_SIZE);
                            if (copied == -1)
                                throw new ClientException(SC_NOT_ACCEPTABLE, "Chart archive exceeds maximum size: " + MAX_FILE_SIZE);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    } else {
                        throw new ClientException(SC_BAD_REQUEST, "Chart archive not found");
                    }
                } catch (FileUploadException|IOException e) {
                    throw new RuntimeException(e);
                }
            } else {
                try (var is = request.getInputStream()) {
                    var copied = IOUtils.copyWithMaxSize(is, baos, MAX_FILE_SIZE);
                    if (copied == -1)
                        throw new ClientException(SC_NOT_ACCEPTABLE, "Chart archive exceeds maximum size: " + MAX_FILE_SIZE);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }    
            }
            Map<String, Object> metadata = null;
            var bytes = baos.toByteArray();

            try (var is = new TarInputStream(new GZIPInputStream(new ByteArrayInputStream(bytes)))) {
                TarEntry entry;

View on GitHub (pinned to d44925c47c)

Solutions

  1. Attach the chart archive as the first file part of the multipart request (e.g. curl -F "chart@mychart-0.1.0.tgz").
  2. Use helm push or the official OneDev client instead of hand-rolled requests.
  3. Check that the HTTP client actually reads the file (non-empty path) before sending.
  4. Inspect request logs/proxy to confirm the body is not stripped (Content-Length > 0).

Example fix

// before (no file attached)
curl -X POST -H "Content-Type: multipart/form-data" https://onedev/~project/helm
// after
curl -X POST -F "chart@mychart-0.1.0.tgz" https://onedev/~project/helm
Defensive patterns

Strategy: validation

Validate before calling

# verify the file exists and is non-empty before upload
[ -s mychart-0.1.0.tgz ] || { echo 'chart archive missing'; exit 1; }
# then attach it explicitly
curl -f -X POST -F "chart@mychart-0.1.0.tgz" https://onedev/~project/helm

Try / catch

try {
    uploadChart(path);
} catch (ClientException e) {
    if (String(e).contains('Chart archive not found')) throw new IllegalStateException("Multipart body must include the chart file part", e);
    throw e;
}

Prevention

When it happens

Trigger: POST to the helm publish endpoint with multipart content type but zero file parts, or with only non-file form fields.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/5c9352e04ab8eb3c. Report an issue: GitHub.