flowable/flowable-engine · error · FlowableIllegalArgumentException
Value of type ${value.getClass()} is not supported as multi
Error message
Value of type ${value.getClass()} is not supported as multi part content What it means
When building multipart bodies, setRequestEntity only supports String values (text parts, optionally with a mime type) — null values are skipped. Any other non-null object type is rejected with FlowableIllegalArgumentException naming the offending Java type, because there is no defined mapping to a MIME part.
Source
Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/impl/apache/ApacheHttpComponentsFlowableHttpClient.java:274
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(multipartMode);
for (MultiValuePart part : requestInfo.getMultiValueParts()) {
String name = part.getName();
Object value = part.getBody();
if (value instanceof byte[]) {
if (StringUtils.isNotBlank(part.getMimeType())) {
entityBuilder.addBinaryBody(name, (byte[]) value, ContentType.create(part.getMimeType()), part.getFilename());
} else {
entityBuilder.addBinaryBody(name, (byte[]) value, ContentType.DEFAULT_BINARY, part.getFilename());
}
} else if (value instanceof String) {
if (StringUtils.isNotBlank(part.getMimeType())) {
entityBuilder.addTextBody(name, (String) value, ContentType.create(part.getMimeType()));
} else {
entityBuilder.addTextBody(name, (String) value);
}
} else if (value != null) {
throw new FlowableIllegalArgumentException("Value of type " + value.getClass() + " is not supported as multi part content");
}
}
requestBase.setEntity(entityBuilder.build());
} else {
throw new FlowableException("org.apache.http.entity.mime.MultipartEntityBuilder is not present on the classpath."
+ " Multi value parts cannot be used."
+ " If you want to use, please make sure that the org.apache.httpcomponents:httpmime dependency is available");
}
} else if (requestInfo.getFormParameters() != null) {
Map<String, List<String>> formParameters = requestInfo.getFormParameters();
List<BasicNameValuePair> parameters = new ArrayList<>(formParameters.size());
for (Map.Entry<String, List<String>> entry : formParameters.entrySet()) {
String name = entry.getKey();
for (String value : entry.getValue()) {
parameters.add(new BasicNameValuePair(name, value));
}
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Convert the value to String before the task (String.valueOf or serialization in a script/listener)
- For binary content, check which part types the configured client supports and use the appropriate field type/format
- Fix the variable producer so the bound variable is a String
- Split the request: send non-string data as JSON body instead of multipart
Example fix
// before
execution.setVariable("amount", 42); // bound to multipart field
// after
execution.setVariable("amount", String.valueOf(42)); Defensive patterns
Strategy: type-guard
Validate before calling
Object v = execution.getVariable("partValue");
if (v != null && !(v instanceof String)) {
execution.setVariable("partValue", String.valueOf(v));
} Type guard
boolean isMultipartCompatible(Object v) { return v == null || v instanceof String; } Try / catch
try {
client.prepareRequest(requestInfo);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("not supported as multi part content")) {
// stringify the offending variable and retry once
} else { throw e; }
} Prevention
- Only bind String variables to multipart fields
- Stringify/serialize non-String values in a preceding script or service task
- Send structured/binary data as a JSON body or supported binary part instead of a generic value
When it happens
Trigger: A multipart field (fieldValue / part value) in the HTTP task resolves to a non-String object — e.g. an Integer, byte[], Map, or POJO process variable — while the request has parts configured.
Common situations: Binding a numeric or binary variable from a previous service task into a multipart field; JSON-deserialized objects used directly as part values; forgetting to convert a file's bytes to a supported representation.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Multipart request is required
- Value of type ${value.getClass()} is not supported as multi
- Invalid usage of async_activate job handler, variable scope
- Invalid usage of ${TYPE} job handler, variable scope is of t
- Delegate expression ${expression} did not resolve to an impl
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e35121e0511eaa13.
Report an issue: GitHub.