flowable/flowable-engine · info · FlowableObjectNotFoundException
Job with id '${jobId}' does not have an exception stacktrace
Error message
Job with id '${jobId}' does not have an exception stacktrace. What it means
getJobStacktrace fetches a job and then its stored exception stacktrace; when managementService.getJobExceptionStacktrace returns null (the job exists but never failed, so no stacktrace was recorded), a FlowableObjectNotFoundException (String.class) is thrown.
Source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/management/JobExceptionStacktraceResource.java:51
* @author Joram Barrez
*/
@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("/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() + "' does not 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("/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
- Only request the stacktrace for jobs whose retries were decremented / that are in failed state.
- Treat a 404 here as 'no failure recorded yet' rather than a missing job.
- Check the job's exception message first via the job resource before fetching the stacktrace.
- Wait for the next failure if the job is expected to fail but has not executed yet.
Example fix
// before curl http://localhost:8080/flowable-rest/management/jobs/7/exception-stacktrace // 404 // after: verify the job actually failed first curl http://localhost:8080/flowable-rest/management/jobs/7 | jq '.exceptionMessage' # only fetch stacktrace when exceptionMessage is non-null
Defensive patterns
Strategy: try-catch
Validate before calling
const job = await fetch(`${base}/management/jobs/${jobId}`).then(r => r.json());
if (!job.exceptionMessage) return null; // no stacktrace exists yet Type guard
function hasRecordedFailure(job) { return !!job && typeof job.exceptionMessage === 'string' && job.exceptionMessage.length > 0; } Try / catch
try {
const trace = await getJobStacktrace(jobId);
} catch (e) {
if (e.status === 404) return null; // job has no failure recorded
throw e;
} Prevention
- Only fetch stacktraces for jobs reporting a non-null exceptionMessage.
- Interpret 404 on stacktrace endpoints as 'no failure yet', not 'job missing'.
- For repeatedly failing jobs check deadletter-jobs, which keeps the final stacktrace.
When it happens
Trigger: GET /management/jobs/{jobId}/exception-stacktrace for a job that has not yet thrown an exception (e.g. a healthy waiting timer or a freshly created job).
Common situations: Monitoring scripts that poll stacktraces for every job, jobs retried successfully so the stacktrace column was cleared, or fetching before the first failed execution.
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
- Could not find a job with id ''.
- Timer job with id '${jobId}' does not have an exception stac
- Suspended job with id '${jobId}' does not have an exception
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/fb4982d93ef802b7.
Report an issue: GitHub.