quarkusio/quarkus · error · RuntimeException

Form value is a file

Error message

Form value is a file

What it means

FormData.StringValue.getValue() throws when the form value was actually uploaded as a file, not a string. The internal form-data entry stores either a string or a FileItem; calling the string accessor on a file entry is a programming error by the parameter reader. The runtime signals this with a plain RuntimeException.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormData.java:298

            this.fileItemImpl = new FileItemImpl(file);
            this.headers = headers;
            this.fileName = fileName;
            this.value = null;
            this.charset = null;
        }

        FormValueImpl(byte[] data, String fileName, CaseInsensitiveMap<String> headers) {
            this.fileItemImpl = new FileItemImpl(data);
            this.fileName = fileName;
            this.headers = headers;
            this.value = null;
            this.charset = null;
        }

        @Override
        public String getValue() {
            if (value == null) {
                throw new RuntimeException("Form value is a file");
            }
            return value;
        }

        @Override
        public String getCharset() {
            return charset;
        }

        @Override
        public FileItemImpl getFileItem() {
            if (fileItemImpl == null) {
                throw new RuntimeException("Form value is a string");
            }
            return fileItemImpl;
        }

        @Override

View on GitHub (pinned to e1c734241f)

Solutions

  1. Declare the endpoint parameter as FileUpload (io.quarkus.runtime.FileUpload) or Path instead of String for that @RestForm attribute.
  2. Check isFileItem() before calling getValue() on the FormData value.
  3. Have the client send the part as a plain field (no filename) if a string is expected.
  4. Use getFileItem() on the value when isFileItem() returns true and read its content.

Example fix

// before
@RestForm String avatar; // breaks when a file is posted
// after
@RestForm FileUpload avatar;
// then: avatar.uploadedFile() / java.nio.file.Files.readAllBytes(...)
Defensive patterns

Strategy: type-guard

Validate before calling

if (value.isFileItem()) { throw new BadRequestException("expected a text field, got a file"); }

Type guard

boolean isString(FormData.FormValue v) { return v != null && !v.isFileItem(); }

Try / catch

try { return value.getValue(); } catch (RuntimeException e) { if ("Form value is a file".equals(e.getMessage())) return null; throw e; }

Prevention

When it happens

Trigger: Calling FormData attribute getValue() (or injecting a @RestForm String for an attribute) when the client sent a multipart file upload for that part, or the server-side @PartType maps it to FileUpload.

Common situations: A client changes the upload from a text field to a file input; the endpoint declares String parameter but the client posts multipart/form-data with a filename; shared code reading form values without checking isFileItem().

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/19f5e23c8b124f84. Report an issue: GitHub.