{"record":{"id":"ef804fd3c76dfa87","repo":"flowable/flowable-engine","slug":"failed-to-serialize-to-a-attachmentrequest-instanc","errorCode":null,"errorMessage":"Failed to serialize to a AttachmentRequest instance","messagePattern":"Failed to serialize to a AttachmentRequest instance","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskAttachmentCollectionResource.java","lineNumber":113,"sourceCode":"    @PostMapping(value = \"/runtime/tasks/{taskId}/attachments\", produces = \"application/json\", consumes = {\"application/json\", \"multipart/form-data\"})\n    @ResponseStatus(HttpStatus.CREATED)\n    public AttachmentResponse createAttachment(@ApiParam(name = \"taskId\") @PathVariable String taskId, HttpServletRequest request) {\n\n        AttachmentResponse result = null;\n        Task task = getTaskFromRequestWithoutAccessCheck(taskId);\n        if (restApiInterceptor != null) {\n            restApiInterceptor.createTaskAttachment(task);\n        }\n        if (request instanceof MultipartHttpServletRequest) {\n            result = createBinaryAttachment((MultipartHttpServletRequest) request, task);\n        } else {\n\n            AttachmentRequest attachmentRequest = null;\n            try {\n                attachmentRequest = objectMapper.readValue(request.getInputStream(), AttachmentRequest.class);\n\n            } catch (Exception e) {\n                throw new FlowableIllegalArgumentException(\"Failed to serialize to a AttachmentRequest instance\", e);\n            }\n\n            if (attachmentRequest == null) {\n                throw new FlowableIllegalArgumentException(\"AttachmentRequest properties not found in request\");\n            }\n\n            result = createSimpleAttachment(attachmentRequest, task);\n        }\n\n        return result;\n    }\n\n    protected AttachmentResponse createSimpleAttachment(AttachmentRequest attachmentRequest, Task task) {\n\n        if (attachmentRequest.getName() == null) {\n            throw new FlowableIllegalArgumentException(\"Attachment name is required.\");\n        }\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskAttachmentCollectionResource.java#L95-L131","documentation":"POSTing a task attachment as JSON requires the body to deserialize into an AttachmentRequest. If Jackson cannot parse the payload (invalid JSON, wrong types, wrong Content-Type), Flowable throws FlowableIllegalArgumentException(\"Failed to serialize to a AttachmentRequest instance\") wrapping the parse exception.","triggerScenarios":"POST /runtime/tasks/{taskId}/attachments with malformed JSON, non-JSON payload sent as application/json, or fields whose types do not match AttachmentRequest (name/description/externalUrl/type as non-strings).","commonSituations":"Multipart vs JSON confusion (JSON branch expects a JSON body, not form-data), hand-built JSON with unescaped quotes, missing Content-Type header, truncated uploads.","solutions":["Validate the JSON body locally before sending.","Send Content-Type: application/json with a body like {\"name\":\"doc\",\"description\":\"...\",\"externalUrl\":\"...\"}.","For binary uploads use the binary-attachment endpoint/multipart form instead of the JSON branch.","Check the server log cause for the exact Jackson error and fix the offending field type."],"exampleFix":"// before\n-d 'name=report'  // not JSON\n\n// after\n-H 'Content-Type: application/json' -d '{\"name\":\"report\",\"description\":\"Q3 report\"}'","handlingStrategy":"validation","validationCode":"const payload = { name: 'doc', description: 'd', externalUrl: 'https://...' };\nconst json = JSON.stringify(payload);\nJSON.parse(json); // local parse check\nawait post(url, json, { headers: { 'Content-Type': 'application/json' } });","typeGuard":"function isAttachmentRequest(v) {\n  return v != null && typeof v.name === 'string'\n    && (v.description === undefined || typeof v.description === 'string')\n    && (v.externalUrl === undefined || typeof v.externalUrl === 'string');\n}","tryCatchPattern":"try {\n  await api.post(`/tasks/${taskId}/attachments`, payload);\n} catch (e) {\n  if (/Failed to serialize to a AttachmentRequest/.test(e.response?.data?.message || '')) {\n    // fix JSON structure/types before retrying\n  }\n}","preventionTips":["Send valid JSON with Content-Type: application/json.","Do not mix multipart and JSON on the same endpoint branch.","Escape quotes/newlines in hand-built JSON."],"tags":["rest-api","json","deserialization","attachments","flowable"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}