flowable/flowable-engine · error · FlowableException

A request body was expected when executing the form submit.

Error message

A request body was expected when executing the form submit.

What it means

submitForm is declared with @RequestBody, so Spring would normally reject empty bodies, but Flowable guards explicitly: if the deserialized SubmitFormRequest is null (e.g. body was empty/whitespace or Content-Type mismatch prevented binding), it throws FlowableException with this message. It protects downstream code from dereferencing a null request object.

Solutions

  1. Send a valid JSON body with Content-Type: application/json
  2. Ensure the body contains at least taskId or processDefinitionId plus form properties
  3. Catch FlowableException mapped to HTTP 400 and validate the client payload before sending

Example fix

// before
curl -X POST -H "Content-Type: application/json" http://localhost:8080/flowable-rest/form/form-data

// after
curl -X POST -H "Content-Type: application/json" \
  -d '{"taskId":"125","formProperties":[{"id":"approved","value":"true"}]}' \
  http://localhost:8080/flowable-rest/form/form-data
Defensive patterns

Strategy: validation

Validate before calling

if (!body || typeof body !== 'object') throw new Error('submitForm requires a JSON body');
if (!body.taskId && !body.processDefinitionId) throw new Error('taskId or processDefinitionId required');

Type guard

function isSubmitFormRequest(v) { return v !== null && typeof v === 'object' && ('taskId' in v || 'processDefinitionId' in v); }

Try / catch

try { await submitForm(payload); } catch (e) { if (e.status === 400) showPayloadError(e); else throw e; }

Prevention

When it happens

Trigger: POST /form/form-data with an empty body, a body that is literally 'null', or a request whose Content-Type is not application/json so no body is bound.

Common situations: HTTP clients omitting -d/--data in curl; wrong Content-Type header (text/plain or form-urlencoded); proxies stripping the body on POST.

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


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

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/form/FormDataResource.java:106

        }
        
        if (restApiInterceptor != null) {
            restApiInterceptor.accessFormData(formData);
        }

        return restResponseFactory.createFormDataResponse(formData);
    }

    @ApiOperation(value = "Submit task form data", tags = { "Forms" })
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Indicates request was successful and the form data was submitted"),
            @ApiResponse(code = 204, message = "If TaskId has been provided, Indicates request was successful and the form data was submitted. Returns empty"),
            @ApiResponse(code = 400, message = "Indicates an parameter was passed in the wrong format. The status-message contains additional information.") })
    @PostMapping(value = "/form/form-data", produces = "application/json")
    public ProcessInstanceResponse submitForm(@RequestBody SubmitFormRequest submitRequest, HttpServletResponse response) {

        if (submitRequest == null) {
            throw new FlowableException("A request body was expected when executing the form submit.");
        }

        if (submitRequest.getTaskId() == null && submitRequest.getProcessDefinitionId() == null) {
            throw new FlowableIllegalArgumentException("The taskId or processDefinitionId property has to be provided");
        }
        
        if (restApiInterceptor != null) {
            restApiInterceptor.submitFormData(submitRequest);
        }

        Map<String, String> propertyMap = new HashMap<>();
        if (submitRequest.getProperties() != null) {
            for (RestFormProperty formProperty : submitRequest.getProperties()) {
                propertyMap.put(formProperty.getId(), formProperty.getValue());
            }
        }

        if (submitRequest.getTaskId() != null) {

View on GitHub (pinned to d6d39ce1c6)