halo-dev/halo · error · ServerWebInputException

Invalid part of file

Error message

Invalid part of file

What it means

Thrown as a ServerWebInputException (HTTP 400) by AvatarUploadRequest.getFile() when a part named 'file' exists but is NOT an instance of FilePart — typically it is a FormFieldPart (a plain text field) rather than an uploaded file.

Source

Thrown at application/src/main/java/run/halo/app/core/endpoint/console/UserEndpoint.java:405

    }

    /** Multipart payload for uploading a user avatar. */
    @Schema(types = "object")
    public interface IAvatarUploadRequest {
        /** Avatar file. */
        @Schema(requiredMode = REQUIRED)
        FilePart getFile();
    }

    public record AvatarUploadRequest(MultiValueMap<String, Part> formData) {
        public FilePart getFile() {
            Part file = formData.getFirst("file");
            if (file == null) {
                throw new ServerWebInputException("No file part found in the request");
            }

            if (!(file instanceof FilePart filePart)) {
                throw new ServerWebInputException("Invalid part of file");
            }

            boolean isNoneExt = Arrays.stream(ALLOWED_AVATAR_EXTENSIONS)
                    .noneMatch(ext -> filePart.filename().endsWith("." + ext));

            if (isNoneExt) {
                throw new ServerWebInputException(
                        "Only support file with extension: " + String.join(", ", ALLOWED_AVATAR_EXTENSIONS));
            }
            return filePart;
        }
    }

    private Mono<Attachment> uploadAvatar(AvatarUploadRequest uploadRequest) {
        var fallbackSetting = environmentFetcher
                .fetch(SystemSetting.User.GROUP, SystemSetting.User.class)
                .mapNotNull(SystemSetting.User::getAvatarPolicy)
                .filter(StringUtils::isNotBlank);

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Attach the avatar as a file upload under the 'file' field (use type 'file' / '@file' semantics in your HTTP client), not a string.
  2. Confirm the multipart part has a filename and Content-Type header, which is what makes WebFlux parse it as a FilePart.

Example fix

// before: client sends file as text  ->  file='/path/me.png'
// after:  client sends file as upload ->  file=@/path/me.png (type=file)
Defensive patterns

Strategy: validation

Validate before calling

// ensure the part is a real file upload, not a text value
if (!(selectedFile instanceof Blob) && !(selectedFile instanceof File)) {
    showUserError("Attach an actual file, not text");
    return;
}

Prevention

When it happens

Trigger: POST to the avatar upload endpoint where the 'file' field is submitted as a normal text form field (e.g. -F 'file=some-string') instead of as a file attachment (-F 'file=@path').

Common situations: Client serialized the file path string into the field instead of attaching the binary; misconfigured form library sent the field as text; API client set 'file' as a string parameter rather than a file upload parameter.

Related errors


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