flowable/flowable-engine · error · FlowableObjectNotFoundException

Job with id '' doesn't have an exception stacktrace.

Error message

Job with id '' doesn't have an exception stacktrace.

What it means

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.

Source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/management/JobExceptionStacktraceResource.java:50

 * @author Tijs Rademakers
 */
@RestController
@Api(tags = { "Jobs" }, authorizations = { @Authorization(value = "basicAuth") })
public class JobExceptionStacktraceResource extends JobBaseResource {

    @ApiOperation(value = "Get the exception stacktrace for a job", tags = { "Jobs" })
    @ApiResponses(value = {
            @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."),
            @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.")
    })
    @GetMapping("/cmmn-management/jobs/{jobId}/exception-stacktrace")
    public String getJobStacktrace(@ApiParam(name = "jobId") @PathVariable String jobId, HttpServletResponse response) {
        Job job = getJobById(jobId);

        String stackTrace = managementService.getJobExceptionStacktrace(job.getId());

        if (stackTrace == null) {
            throw new FlowableObjectNotFoundException("Job with id '" + job.getId() + "' doesn't have an exception stacktrace.", String.class);
        }

        response.setContentType("text/plain");
        return stackTrace;
    }

    @ApiOperation(value = "Get the exception stacktrace for a timer job", tags = { "Jobs" })
    @ApiResponses(value = {
            @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."),
            @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.")
    })
    @GetMapping("/cmmn-management/timer-jobs/{jobId}/exception-stacktrace")
    public String getTimerJobStacktrace(@ApiParam(name = "jobId") @PathVariable String jobId, HttpServletResponse response) {
        Job job = getTimerJobById(jobId);

        String stackTrace = managementService.getTimerJobExceptionStacktrace(job.getId());

        if (stackTrace == null) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Only request the stacktrace for jobs in a failed/error state (check the job's response fields first).
  2. Handle 404 on this endpoint as 'no stacktrace yet' and re-check after the job fails.
  3. Inspect job exception message via the job list response instead of the stacktrace endpoint when null is expected.

Example fix

// before
String st = client.get("/cmmn-management/jobs/" + id + "/exception-stacktrace");
// after
if (jobResponse.isFailed()) {
    String st = client.get("/cmmn-management/jobs/" + id + "/exception-stacktrace");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!jobResponse.exceptionMessage) { /* job has not failed; skip stacktrace call */ }

Try / catch

try { st = getStacktrace(id) } catch (e) { if (e.status === 404) return null; throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: Polling stacktrace for a job awaiting its first execution; requesting stacktrace right after the job was created; assuming all job types carry stacktraces.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/9038259883b488cf. Report an issue: GitHub.