flowable/flowable-engine · error · FlowableIllegalArgumentException
Attachment content is required.
Error message
Attachment content is required.
What it means
Thrown by TaskAttachmentCollectionResource.createBinaryAttachment when a multipart request to create a binary task attachment contains no file part. The Flowable REST API requires uploaded content for binary attachments; name and description alone are insufficient, so the request is rejected as an illegal argument.
Solutions
- Include a file part in the multipart request, e.g. curl -F 'file=@document.pdf' -F 'name=My attachment'
- Verify the client library actually sends multipart/form-data (not urlencoded or raw body)
- Check no intermediary (proxy/gateway) strips the file part
- Confirm the endpoint is the binary one (POST .../attachments/content) when uploading content
Example fix
// before
curl -X POST -F 'name=report' http://host/flowable-rest/runtime/tasks/{taskId}/attachments
// after
curl -X POST -F 'name=report' -F 'file=@report.pdf' http://host/flowable-rest/runtime/tasks/{taskId}/attachments Defensive patterns
Strategy: validation
Validate before calling
const hasFile = formData.get('file') instanceof File && formData.get('file').size > 0;
if (!hasFile) throw new Error('A non-empty file part is required for binary attachment upload'); Type guard
function hasFilePart(fd) { const f = fd.get('file'); return f instanceof File && f.size > 0; } Try / catch
try { await api.createBinaryAttachment(taskId, formData); } catch (e) { if (e.status === 400 && /content is required/.test(e.message)) { alert('Attach a file before submitting'); } else { throw e; } } Prevention
- Always append a file part named 'file' to the multipart form
- Check file.size > 0 before uploading
- Use the metadata endpoint instead when no content should be stored
- Test uploads with curl -F to verify the multipart encoding
When it happens
Trigger: POST to /runtime/tasks/{taskId}/attachments with multipart/form-data but zero file entries in the request's file map (request.getFileMap().size() == 0).
Common situations: Client sends only form fields (name/description/type) without a file part; using the wrong multipart field name so the server doesn't recognize the file; testing with curl -F 'name=x' but forgetting -F 'file=@...'; a proxy stripping the file part.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Multipart request is required
- Multipart request is required
- Multipart request is required
- Multipart request is required
- Multipart request with file content is required
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/68f29756dfbd89dd.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskAttachmentCollectionResource.java:165
if ("name".equalsIgnoreCase(parameterName)) {
name = paramMap.get(parameterName)[0];
} else if ("description".equalsIgnoreCase(parameterName)) {
description = paramMap.get(parameterName)[0];
} else if ("type".equalsIgnoreCase(parameterName)) {
type = paramMap.get(parameterName)[0];
}
}
}
if (name == null) {
throw new FlowableIllegalArgumentException("Attachment name is required.");
}
if (request.getFileMap().size() == 0) {
throw new FlowableIllegalArgumentException("Attachment content is required.");
}
MultipartFile file = request.getFileMap().values().iterator().next();
if (file == null) {
throw new FlowableIllegalArgumentException("Attachment content is required.");
}
try {
Attachment createdAttachment = taskService.createAttachment(type, task.getId(), task.getProcessInstanceId(), name, description, file.getInputStream());
return restResponseFactory.createAttachmentResponse(createdAttachment);
} catch (Exception e) {
throw new FlowableException("Error creating attachment response", e);
}
}
}View on GitHub (pinned to d6d39ce1c6)