halo-dev/halo · warning · ServerWebInputException

Invalid part of file

Error message

Invalid part of file

What it means

UploadRequest is the multipart upload payload. getFile() throws ServerWebInputException (HTTP 400) 'Invalid part of file' when the multipart form either has no "file" part at all or the part is not a FilePart (e.g. it is a plain FormFieldPart). Halo needs an actual file part to stream into attachment storage.

Source

Thrown at application/src/main/java/run/halo/app/core/attachment/endpoint/AttachmentEndpoint.java:169

        /** Attachment file. */
        @Schema(requiredMode = REQUIRED)
        FilePart getFile();

        /** Storage policy {@code metadata.name}. */
        @Schema(requiredMode = REQUIRED)
        String getPolicyName();

        /** Attachment group {@code metadata.name}. */
        String getGroupName();
    }

    public record UploadRequest(MultiValueMap<String, Part> formData) implements IUploadRequest {

        public FilePart getFile() {
            if (formData.getFirst("file") instanceof FilePart file) {
                return file;
            }
            throw new ServerWebInputException("Invalid part of file");
        }

        public String getPolicyName() {
            if (formData.getFirst("policyName") instanceof FormFieldPart form) {
                return form.value();
            }
            throw new ServerWebInputException("Invalid part of policyName");
        }

        @Override
        public String getGroupName() {
            if (formData.getFirst("groupName") instanceof FormFieldPart form) {
                return form.value();
            }
            return null;
        }
    }
}

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Send the request as multipart/form-data with a real file under the "file" field.
  2. Ensure the file input has a selected file before submit.
  3. Check proxy/CDN max-body-size settings if large uploads lose their file part.

Example fix

// before
const fd = new FormData();
fd.append('policyName', 'default');
// missing fd.append('file', ...)

// after
const fd = new FormData();
fd.append('file', selectedFile);
fd.append('policyName', 'default');
Defensive patterns

Strategy: validation

Validate before calling

if (!(formData.getFirst("file") instanceof FilePart file)) {
    return Mono.error(new ServerWebInputException("Invalid part of file"));
}

Type guard

static boolean hasFilePart(MultiValueMap<String, Part> fd) {
    return fd.getFirst("file") instanceof FilePart;
}

Prevention

When it happens

Trigger: Multipart POST to the attachment upload endpoint with no file field; a file field sent as a regular form field; a request where the file part was dropped by a proxy/CDN due to size limits.

Common situations: Frontend uses application/x-www-form-urlencoded instead of multipart/form-data; the file input was left empty and the browser omitted the field; a reverse proxy stripped the multipart file part.

Related errors


AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14). Data as JSON: /api/errors/db269857529fe156. Report an issue: GitHub.