flowable/flowable-engine · error · FlowableObjectNotFoundException

Could not find a history job with id ''.

Error message

Could not find a history job with id ''.

What it means

validateHistoryJob throws FlowableObjectNotFoundException when no HistoryJob exists for the given id; getHistoryJobById uses it. Distinguishes history (permanent log) jobs from ordinary runtime jobs, which are validated by the sibling validateJob.

Source

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

    protected HistoryJob getHistoryJobById(String jobId) {
        HistoryJob job = managementService.createHistoryJobQuery().jobId(jobId).singleResult();
        validateHistoryJob(job, jobId);
        return job;
    }
    
    protected void validateJob(Job job, String jobId) {
        if (job == null) {
            throw new FlowableObjectNotFoundException("Could not find a job with id '" + jobId + "'.", Job.class);
        }
        
        if (restApiInterceptor != null) {
            restApiInterceptor.accessJobInfoById(job);
        }
    }

    protected void validateHistoryJob(HistoryJob job, String jobId) {
        if (job == null) {
            throw new FlowableObjectNotFoundException("Could not find a history job with id '" + jobId + "'.", HistoryJob.class);
        }

        if (restApiInterceptor != null) {
            restApiInterceptor.accessHistoryJobInfoById(job);
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Confirm the id refers to a history job by querying /cmmn-management/history/jobs first.
  2. If the job is a runtime job, use the matching runtime job endpoint.
  3. Handle 404 as 'history job gone' (e.g. deleted by history cleanup).

Example fix

// before
String stack = client.get("/cmmn-management/history/jobs/" + runtimeJobId);
// after
String stack = client.get("/cmmn-management/history/jobs/" + historyJobId);
Defensive patterns

Strategy: try-catch

Validate before calling

const isHistoryJob = historyJobs.some(j => j.id === jobId);

Try / catch

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

Prevention

When it happens

Trigger: GET /cmmn-management/history/jobs/{jobId} with an id that is not a history job — including ids of runtime/timer/dead-letter jobs or already-deleted history jobs.

Common situations: Using a runtime job id against the history endpoint; history cleanup already deleted the job; id from a different engine database.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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