{"record":{"id":"2e841d1ececc7c61","repo":"flowable/flowable-engine","slug":"job-jobid-failed-2e841d","errorCode":null,"errorMessage":"Job ${jobId} failed","messagePattern":"Job (.+?) failed","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/ManagementServiceImpl.java","lineNumber":153,"sourceCode":"    public String getTableName(Class<?> entityClass, boolean includePrefix) {\n        return commandExecutor.execute(new GetTableNameCmd(entityClass, includePrefix));\n    }\n\n    @Override\n    public TableMetaData getTableMetaData(String tableName) {\n        return commandExecutor.execute(new GetTableMetaDataCmd(tableName, configuration.getEngineCfgKey()));\n    }\n\n    @Override\n    public void executeJob(String jobId) {\n        try {\n            commandExecutor.execute(new ExecuteJobCmd(jobId, configuration.getJobServiceConfiguration()));\n\n        } catch (RuntimeException e) {\n            if (e instanceof FlowableException) {\n                throw e;\n            } else {\n                throw new FlowableException(\"Job \" + jobId + \" failed\", e);\n            }\n        }\n    }\n    \n    @Override\n    public void executeHistoryJob(String historyJobId) {\n        commandExecutor.execute(new ExecuteHistoryJobCmd(historyJobId, configuration.getJobServiceConfiguration()));\n    }\n\n    @Override\n    public String getHistoryJobHistoryJson(String historyJobId) {\n        return commandExecutor.execute(new GetHistoryJobAdvancedConfigurationCmd(historyJobId, configuration.getJobServiceConfiguration()));\n    }\n\n    @Override\n    public Job moveTimerToExecutableJob(String jobId) {\n        return commandExecutor.execute(new MoveTimerToExecutableJobCmd(jobId, configuration.getJobServiceConfiguration()));\n    }","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/ManagementServiceImpl.java#L135-L171","documentation":"ManagementService.executeJob(String) wraps job execution (ExecuteJobCmd) and, when a non-Flowable RuntimeException escapes the command, rethrows it as a FlowableException with message \"Job <jobId> failed\" and the original as cause. FlowableExceptions themselves are rethrown unchanged. This normalizes unexpected runtime failures (NPE, IllegalStateException, etc.) during job execution.","triggerScenarios":"Calling managementService.executeJob(jobId) where the job's handler throws a non-Flowable RuntimeException — e.g. a NullPointerException in a service task, class-cast errors in a delegate, or a broken job configuration.","commonSituations":"Manually re-executing a dead-letter/async job whose delegate class changed between deployments; jobs touching missing beans or classes causing RuntimeExceptions inside the command.","solutions":["Inspect the cause via e.getCause() — the real failure is the wrapped exception","Fix the underlying job delegate/handler that threw the RuntimeException","Redeploy the job's associated definition/classes so resolution succeeds","Check the Flowable job log/exception stack for the original failure point"],"exampleFix":"// before\nmanagementService.executeJob(jobId);\n// after\ntry {\n    managementService.executeJob(jobId);\n} catch (FlowableException e) {\n    Throwable cause = e.getCause();\n    LOG.error(\"Job failed: {}\", cause != null ? cause.getMessage() : e.getMessage(), cause != null ? cause : e);\n}","handlingStrategy":"try-catch","validationCode":"// verify the job exists and inspect its last failure before re-executing\nJob job = managementService.createJobQuery().jobId(jobId).singleResult();\nif (job == null || job.getExceptionMessage() != null) {\n    LOG.warn(\"Job {} previously failed: {}\", jobId, job != null ? job.getExceptionMessage() : \"not found\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    managementService.executeJob(jobId);\n} catch (FlowableException e) {\n    Throwable root = e.getCause() != null ? e.getCause() : e;\n    LOG.error(\"Job \" + jobId + \" failed due to \" + root.getClass().getSimpleName(), root);\n}","preventionTips":["Always inspect getCause() — the \"Job X failed\" message wraps the real RuntimeException","Keep delegate classes stable across deployments or ensure the same classes are on the classpath when re-running old jobs","Log and monitor job exceptionMessage via JobQuery to fix root causes before manual re-execution"],"tags":["flowable","job-execution","wrapped-exception","runtime-error"],"backgroundTag":"job-execution-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}