{"record":{"id":"cf0e8b7b039ddd21","repo":"flowable/flowable-engine","slug":"multipart-request-is-required-cf0e8b","errorCode":null,"errorMessage":"Multipart request is required","messagePattern":"Multipart request is required","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ModelSourceExtraResource.java","lineNumber":82,"sourceCode":"\n    @ApiOperation(value = \"Set the extra editor source for a model\", tags = { \"Models\" }, nickname = \"setExtraEditorSource\", consumes = \"multipart/form-data\",\n            notes = \"Response body contains the model’s raw editor source. The response’s content-type is set to application/octet-stream, regardless of the content of the source.\",\n            code = 204)\n    @ApiImplicitParams({\n            @ApiImplicitParam(name = \"file\", dataType = \"file\", paramType = \"form\", required = true)\n    })\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the model was found and the extra source has been updated.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested model was not found.\")\n    })\n    @PutMapping(value = \"/repository/models/{modelId}/source-extra\", consumes = \"multipart/form-data\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void setModelSource(@ApiParam(name = \"modelId\") @PathVariable String modelId, HttpServletRequest request) {\n        Model model = getModelFromRequest(modelId);\n        try {\n\n            if (!(request instanceof MultipartHttpServletRequest)) {\n                throw new FlowableIllegalArgumentException(\"Multipart request is required\");\n            }\n\n            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;\n\n            if (multipartRequest.getFileMap().size() == 0) {\n                throw new FlowableIllegalArgumentException(\"Multipart request with file content is required\");\n            }\n\n            MultipartFile file = multipartRequest.getFileMap().values().iterator().next();\n\n            repositoryService.addModelEditorSourceExtra(model.getId(), file.getBytes());\n\n        } catch (Exception e) {\n            throw new FlowableException(\"Error adding model editor source extra\", e);\n        }\n    }\n\n}","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ModelSourceExtraResource.java#L64-L100","documentation":"Thrown by PUT /repository/models/{modelId}/source-extra when the request is not a multipart request. The endpoint requires multipart/form-data so the uploaded file can be extracted from the MultipartHttpServletRequest.","triggerScenarios":"PUT /repository/models/{modelId}/source-extra sent with Content-Type application/octet-stream, application/json, or form-urlencoded instead of multipart/form-data; also occurs when a multipart parser/filter is not configured so the request never becomes a MultipartHttpServletRequest.","commonSituations":"Client libraries sending raw byte bodies instead of a file part; missing or misconfigured MultipartResolver/multipart servlet config in the REST app; proxies stripping the Content-Type boundary.","solutions":["Send the request as multipart/form-data with at least one file part (e.g. curl -X PUT -F 'file=@source.xml' ...)","Check the Content-Type header includes the multipart boundary and was not overridden by the HTTP client","Ensure Spring multipart support is enabled in the REST application","Confirm no proxy or filter rewrites the request body/headers"],"exampleFix":"// before\ncurl -X PUT -H 'Content-Type: application/octet-stream' --data-binary @src.xml .../models/id/source-extra\n// after\ncurl -X PUT -F 'file=@src.xml' .../models/id/source-extra","handlingStrategy":"validation","validationCode":"if (!contentType.startsWith(\"multipart/form-data\")) throw new IllegalArgumentException(\"use multipart/form-data with a file part\");","typeGuard":null,"tryCatchPattern":"try { setModelSource(modelId, request); } catch (FlowableIllegalArgumentException e) { log.error(\"send multipart/form-data with a file part\", e); }","preventionTips":["Let the HTTP client set the multipart Content-Type automatically","Include a real file part, not raw bytes","Verify multipart support is enabled in the REST app"],"tags":["flowable","rest","multipart","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}