{"record":{"id":"8c86ea550680e552","repo":"flowable/flowable-engine","slug":"suspended-job-with-id-doesn-t-have-an-exception","errorCode":null,"errorMessage":"Suspended job with id '' doesn't have an exception stacktrace.","messagePattern":"Suspended job with id '' doesn't have an exception stacktrace\\.","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/management/JobExceptionStacktraceResource.java","lineNumber":88,"sourceCode":"        }\n\n        response.setContentType(\"text/plain\");\n        return stackTrace;\n    }\n\n    @ApiOperation(value = \"Get the exception stacktrace for a suspended job\", tags = { \"Jobs\" })\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the requested job was not found and the stacktrace has been returned. The response contains the raw stacktrace and always has a Content-type of text/plain.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested job was not found or the job does not have an exception stacktrace. Status-description contains additional information about the error.\")\n    })\n    @GetMapping(\"/cmmn-management/suspended-jobs/{jobId}/exception-stacktrace\")\n    public String getSuspendedJobStacktrace(@ApiParam(name = \"jobId\") @PathVariable String jobId, HttpServletResponse response) {\n        Job job = getSuspendedJobById(jobId);\n\n        String stackTrace = managementService.getSuspendedJobExceptionStacktrace(job.getId());\n\n        if (stackTrace == null) {\n            throw new FlowableObjectNotFoundException(\"Suspended job with id '\" + job.getId() + \"' doesn't have an exception stacktrace.\", String.class);\n        }\n\n        response.setContentType(\"text/plain\");\n        return stackTrace;\n    }\n\n    @ApiOperation(value = \"Get the exception stacktrace for a deadletter job\", tags = { \"Jobs\" })\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the requested job was not found and the stacktrace has been returned. The response contains the raw stacktrace and always has a Content-type of text/plain.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested job was not found or the job does not have an exception stacktrace. Status-description contains additional information about the error.\")\n    })\n    @GetMapping(\"/cmmn-management/deadletter-jobs/{jobId}/exception-stacktrace\")\n    public String getDeadLetterJobStacktrace(@ApiParam(name = \"jobId\") @PathVariable String jobId, HttpServletResponse response) {\n        Job job = getDeadLetterJobById(jobId);\n\n        String stackTrace = managementService.getDeadLetterJobExceptionStacktrace(job.getId());\n\n        if (stackTrace == null) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/management/JobExceptionStacktraceResource.java#L70-L106","documentation":"Thrown when GET /cmmn-management/suspended-jobs/{jobId}-exception-stacktrace returns a suspended job but the management service has no stored exception stacktrace for it (null). The suspended job exists but has not failed, so there is no stacktrace resource to return.","triggerScenarios":"GET /cmmn-management/suspended-jobs/{jobId}-exception-stacktrace for a suspended job whose stored exception stacktrace is null — typically a job created by suspend-job operations that never threw.","commonSituations":"Inspecting all suspended jobs for failures; calling the endpoint on a freshly suspended job; assuming suspended implies failed.","solutions":["Verify the job actually failed before requesting its stacktrace.","Treat the 404 as informational ('no failure recorded') and continue.","Check the suspended job's exceptionMessage via job query instead of fetching the stacktrace."],"exampleFix":"// before\nString trace = rest.get(pathSuspendedJobStacktrace(jobId));\n// after\nJob job = managementService.createSuspendedJobQuery().jobId(jobId).singleResult();\nString trace = job != null && job.getExceptionMessage() != null\n    ? rest.get(pathSuspendedJobStacktrace(jobId))\n    : null;","handlingStrategy":"try-catch","validationCode":"Job j = managementService.createSuspendedJobQuery().jobId(jobId).singleResult();\nboolean safe = j != null && j.getExceptionMessage() != null;","typeGuard":null,"tryCatchPattern":"try { String s = managementService.getSuspendedJobExceptionStacktrace(jobId); }\ncatch (FlowableObjectNotFoundException e) { /* suspended job has no recorded failure */ }","preventionTips":["Don't assume suspended == failed","Check exceptionMessage via query first","Treat missing stacktrace as informational"],"tags":["flowable","rest-api","job","stacktrace","not-found"],"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-14T05:17:10.506Z"}