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 a multipart body, `setRequestEntity` in the HttpClient 5.x client only accepts `String` and `byte[]` (or null, which is skipped) values for each part. Any other value type reaching this branch throws `FlowableIllegalArgumentException` naming the offending Java class.

Source

Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/impl/apache/client5/ApacheHttpComponents5FlowableHttpClient.java:272

            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");
                }
            }

            try (HttpEntity multiPartEntity = entityBuilder.build();
                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream((int) multiPartEntity.getContentLength())) {
                multiPartEntity.writeTo(outputStream);
                requestBase.setEntity(outputStream.toByteArray(), ContentType.parse(multiPartEntity.getContentType()));
            } catch (IOException e) {
                throw new FlowableException("Cannot create multi part entity", e);
            }
        } 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

  1. Convert the value to `String` (`String.valueOf(value)`) for text parts or `byte[]` for binary parts before adding it as a multipart part.
  2. For files, read the content into a `byte[]` (`Files.readAllBytes(path)`) and supply that as the part value.
  3. Fix the expression/variable mapping that injects the unsupported type into the multi value parts map.

Example fix

// before
parts.put("count", someInteger); // FlowableIllegalArgumentException

// after
parts.put("count", String.valueOf(someInteger));
parts.put("file", Files.readAllBytes(Paths.get("report.pdf")));
Defensive patterns

Strategy: type-guard

Validate before calling

boolean isSupportedPartValue(Object v) {
    return v == null || v instanceof String || v instanceof byte[];
}
// validate every multi value part value before calling the client

Type guard

static boolean isMultipartPartValue(Object value) {
    return value instanceof String || value instanceof byte[];
}
// usage: parts.values().forEach(v -> { if (!isMultipartPartValue(v)) throw new IllegalArgumentException("Part must be String or byte[], got " + v.getClass()); });

Try / catch

try {
    return client.call(requestInfo);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("not supported as multi part content")) {
        log.error("Convert multipart part values to String or byte[] before sending: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: A multi value part parameter whose value is not a `String` or `byte[]` — e.g. an `Integer`, `File`, `InputStream`, or a serialized object placed directly into the part parameters map.

Common situations: Passing numbers/booleans from process variables straight into multipart parts without conversion; attempting to upload a `File` object instead of its bytes; scripting expressions producing non-string values.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/ccfebc996fbf2401. Report an issue: GitHub.