{"record":{"id":"9038259883b488cf","repo":"flowable/flowable-engine","slug":"job-with-id-doesn-t-have-an-exception-stacktrac","errorCode":null,"errorMessage":"Job with id '' doesn't have an exception stacktrace.","messagePattern":"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":50,"sourceCode":" * @author Tijs Rademakers\n */\n@RestController\n@Api(tags = { \"Jobs\" }, authorizations = { @Authorization(value = \"basicAuth\") })\npublic class JobExceptionStacktraceResource extends JobBaseResource {\n\n    @ApiOperation(value = \"Get the exception stacktrace for a 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/jobs/{jobId}/exception-stacktrace\")\n    public String getJobStacktrace(@ApiParam(name = \"jobId\") @PathVariable String jobId, HttpServletResponse response) {\n        Job job = getJobById(jobId);\n\n        String stackTrace = managementService.getJobExceptionStacktrace(job.getId());\n\n        if (stackTrace == null) {\n            throw new FlowableObjectNotFoundException(\"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 timer 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/timer-jobs/{jobId}/exception-stacktrace\")\n    public String getTimerJobStacktrace(@ApiParam(name = \"jobId\") @PathVariable String jobId, HttpServletResponse response) {\n        Job job = getTimerJobById(jobId);\n\n        String stackTrace = managementService.getTimerJobExceptionStacktrace(job.getId());\n\n        if (stackTrace == null) {","sourceCodeStart":32,"sourceCodeEnd":68,"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#L32-L68","documentation":"JobExceptionStacktraceResource.getJobStacktrace returns the exception stacktrace of a job as text/plain. If managementService.getJobExceptionStacktrace returns null — the job exists but never failed — it throws FlowableObjectNotFoundException.","triggerScenarios":"GET /cmmn-management/jobs/{jobId}/exception-stacktrace for a job that has not failed (no exception recorded), or for a timer/suspended job never executed with an error.","commonSituations":"Polling stacktrace for a job awaiting its first execution; requesting stacktrace right after the job was created; assuming all job types carry stacktraces.","solutions":["Only request the stacktrace for jobs in a failed/error state (check the job's response fields first).","Handle 404 on this endpoint as 'no stacktrace yet' and re-check after the job fails.","Inspect job exception message via the job list response instead of the stacktrace endpoint when null is expected."],"exampleFix":"// before\nString st = client.get(\"/cmmn-management/jobs/\" + id + \"/exception-stacktrace\");\n// after\nif (jobResponse.isFailed()) {\n    String st = client.get(\"/cmmn-management/jobs/\" + id + \"/exception-stacktrace\");\n}","handlingStrategy":"validation","validationCode":"if (!jobResponse.exceptionMessage) { /* job has not failed; skip stacktrace call */ }","typeGuard":null,"tryCatchPattern":"try { st = getStacktrace(id) } catch (e) { if (e.status === 404) return null; throw e; }","preventionTips":["Only fetch stacktraces for failed jobs.","Treat 404 as 'no stacktrace yet' in polling loops.","Use the exceptionMessage field from job responses when a full trace isn't needed."],"tags":["rest-api","jobs","resource-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-14T11:17:12.474Z"}