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
- Only query stacktraces for suspended jobs known to have failed (exceptionMessage present).
- If the job failed repeatedly, check dead-letter jobs instead of suspended jobs.
- Handle 404 as 'no recorded failure' in automation.
- 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
- Suspended jobs are usually healthy; only expect stacktraces for those with exceptionMessage set.
- Do not blanket-poll stacktraces across all suspended jobs.
- If diagnosis is needed, move/resume the job to dead-letter where the stacktrace persists.
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
- Timer job with id '' doesn't have an exception stacktrace.
- Suspended job with id '' doesn't have an exception stacktrac
- Job with id '${jobId}' does not have an exception stacktrace
- Timer job with id '${jobId}' does not have an exception stac
- Could not find a case instance with id '${caseInstanceId}'.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/bf6cc200e57a2749.
Report an issue: GitHub.