{"record":{"id":"f0f4e077948e503f","repo":"flowable/flowable-engine","slug":"the-user-with-id-userid-does-not-have-a-pictu","errorCode":null,"errorMessage":"The user with id '${userId}' does not have a picture.","messagePattern":"The user with id '(.+?)' does not have a picture\\.","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/identity/UserPictureResource.java","lineNumber":66,"sourceCode":" */\n@RestController\n@Api(tags = { \"Users\" }, authorizations = { @Authorization(value = \"basicAuth\") })\npublic class UserPictureResource extends BaseUserResource {\n\n\n    @ApiOperation(value = \"Get a user’s picture\", produces = \"application/octet-stream\", tags = {\n            \"Users\" }, notes = \"The response body contains the raw picture data, representing the user’s picture. The Content-type of the response corresponds to the mimeType that was set when creating the picture.\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the user was found and has a picture, which is returned in the body.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested user was not found or the user does not have a profile picture. Status-description contains additional information about the error.\")\n    })\n    @GetMapping(value = \"/identity/users/{userId}/picture\")\n    public ResponseEntity<byte[]> getUserPicture(@ApiParam(name = \"userId\") @PathVariable String userId) {\n        User user = getUserFromRequest(userId);\n        Picture userPicture = identityService.getUserPicture(user.getId());\n\n        if (userPicture == null) {\n            throw new FlowableObjectNotFoundException(\"The user with id '\" + user.getId() + \"' does not have a picture.\", Picture.class);\n        }\n\n        HttpHeaders responseHeaders = new HttpHeaders();\n        if (userPicture.getMimeType() != null) {\n            responseHeaders.set(\"Content-Type\", userPicture.getMimeType());\n        } else {\n            responseHeaders.set(\"Content-Type\", \"image/jpeg\");\n        }\n\n        try {\n            return new ResponseEntity<>(IOUtils.toByteArray(userPicture.getInputStream()), responseHeaders, HttpStatus.OK);\n        } catch (Exception e) {\n            throw new FlowableException(\"Error exporting picture: \" + e.getMessage(), e);\n        }\n    }\n\n    @ApiOperation(consumes = \"multipart/form-data\", value = \"Updating a user’s picture\", tags = {\n            \"Users\" },  notes = \"The request should be of type multipart/form-data. There should be a single file-part included with the binary value of the picture. On top of that, the following additional form-fields can be present:\\n\"","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/identity/UserPictureResource.java#L48-L84","documentation":"FlowableObjectNotFoundException thrown by getUserPicture (GET /identity/users/{userId}/picture) when identityService.getUserPicture(userId) returns null — the user exists but has never been assigned a picture. The resource type in the exception is Picture.class, signaling callers that the missing entity is the picture, not the user.","triggerScenarios":"Requesting GET identity/users/{userId}/picture for a user created without a picture, or before PUT .../picture (upload) has ever been called, or after the picture was deleted/reset to null.","commonSituations":"Frontends that unconditionally render avatar endpoints for all users; users migrated from another identity store without picture blobs; freshly provisioned accounts in test environments; consuming a 404 with resource type 'Picture' and confusing it with 'user not found'.","solutions":["Check for a 404 response on the picture endpoint and render a default avatar instead.","Upload a picture first via PUT identity/users/{userId}/picture (multipart/form-data with a single file part).","Confirm the correct userId — pictures are per-user and not shared.","Use the identityService.setUserPicture(userId, picture) API server-side if provisioning users programmatically."],"exampleFix":"// before\nconst res = await fetch(`/identity/users/${userId}/picture`);\nconst blob = await res.blob(); // throws/unhandled on 404\n\n// after\nconst res = await fetch(`/identity/users/${userId}/picture`);\nif (res.status === 404) {\n  return DEFAULT_AVATAR;\n}\nreturn await res.blob();","handlingStrategy":"fallback","validationCode":"// no cheap pre-check via API besides listing; guard by handling 404\nconst res = await fetch(`/identity/users/${userId}/picture`);\nif (res.status === 404) {\n  return DEFAULT_AVATAR;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(`/identity/users/${userId}/picture`);\n  if (res.status === 404) return DEFAULT_AVATAR; // FlowableObjectNotFoundException: no picture\n  return await res.blob();\n} catch (e) {\n  return DEFAULT_AVATAR;\n}","preventionTips":["Always render a default avatar fallback for the picture endpoint.","Check the 404 resource type: 'Picture' means no picture, not unknown user.","Upload pictures during user provisioning if avatars are required.","Distinguish HTTP 404 (no picture) from HTTP 500 (export/stream failure)."],"tags":["rest","not-found","picture","flowable"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}