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;
}
@OverrideView on GitHub (pinned to e1c734241f)
Solutions
- Declare the endpoint parameter as FileUpload (io.quarkus.runtime.FileUpload) or Path instead of String for that @RestForm attribute.
- Check isFileItem() before calling getValue() on the FormData value.
- Have the client send the part as a plain field (no filename) if a string is expected.
- 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
- Match parameter types to what clients actually send
- Check isFileItem() before getValue()
- Keep @RestForm types consistent with the client form encoding
- Add tests posting both field and file variants
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
- Form value is a string
- Could not find MessageBodyWriter for ${entityClass} as ${med
- Media type '" + mediaType + "' in multipart request is not s
- Extra steps left over
- Unsupported value type: %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/19f5e23c8b124f84.
Report an issue: GitHub.