flowable/flowable-engine · info · FlowableObjectNotFoundException

Suspended job with id '${jobId}' does not have an exception

Error message

Suspended job with id '${jobId}' does not have an exception stacktrace.

What it means

getSuspendedJobStacktrace throws FlowableObjectNotFoundException when managementService.getSuspendedJobExceptionStacktrace returns null for the given suspended job id — the job exists but no exception stacktrace is stored for it.

Source

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

        }

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

    @ApiOperation(value = "Get the exception stacktrace for a suspended 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("/management/suspended-jobs/{jobId}/exception-stacktrace")
    public String getSuspendedJobStacktrace(@ApiParam(name = "jobId") @PathVariable String jobId, HttpServletResponse response) {
        Job job = getSuspendedJobById(jobId);

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

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

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

    @ApiOperation(value = "Get the exception stacktrace for a deadletter 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("/management/deadletter-jobs/{jobId}/exception-stacktrace")
    public String getDeadLetterJobStacktrace(@ApiParam(name = "jobId") @PathVariable String jobId, HttpServletResponse response) {
        Job job = getDeadLetterJobById(jobId);

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

        if (stackTrace == null) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Only query stacktraces for suspended jobs known to have failed (exceptionMessage present).
  2. If the job failed repeatedly, check dead-letter jobs instead of suspended jobs.
  3. Handle 404 as 'no recorded failure' in automation.
  4. Resume the job and let it fail into dead-letter if you need a full stacktrace for diagnosis.

Example fix

// before
curl http://localhost:8080/flowable-rest/management/suspended-jobs/55/exception-stacktrace  // 404
// after: gate on exceptionMessage
curl http://localhost:8080/flowable-rest/management/suspended-jobs/55 | jq '.exceptionMessage'
# only fetch the stacktrace when it is non-null
Defensive patterns

Strategy: try-catch

Validate before calling

const job = await fetch(`${base}/management/suspended-jobs/${jobId}`).then(r => r.json());
if (!job.exceptionMessage) return null; // suspended but never failed

Type guard

function hasRecordedFailure(job) { return !!job && typeof job.exceptionMessage === 'string' && job.exceptionMessage.length > 0; }

Try / catch

try {
  const trace = await getSuspendedJobStacktrace(jobId);
} catch (e) {
  if (e.status === 404) return null;
  throw e;
}

Prevention

When it happens

Trigger: GET /management/suspended-jobs/{jobId}/exception-stacktrace for a suspended job that has never failed execution.

Common situations: Suspended jobs created when a process definition was suspended (they are usually healthy), monitoring scripts iterating all suspended jobs, or jobs whose failure data was cleared on resume/retry.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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