flowable/flowable-engine · info · FlowableObjectNotFoundException

Suspended job with id

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.

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.

Appendix: 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)