{"record":{"id":"1f1e9fe827dcba2b","repo":"flowable/flowable-engine","slug":"exception-during-timer-execution-message-1f1e9f","errorCode":null,"errorMessage":"exception during timer execution: ${message}","messagePattern":"exception during timer execution: (.+?)","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerStartEventJobHandler.java","lineNumber":105,"sourceCode":"\n        if (processDefinition == null) {\n            throw new ActivitiException(\"Could not find process definition needed for timer start event\");\n        }\n\n        try {\n            if (!deploymentManager.isProcessDefinitionSuspended(processDefinition.getId())) {\n                dispatchTimerFiredEvent(job, commandContext);\n\n                new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, null, null, job.getTenantId()).execute(commandContext);\n            } else {\n                LOGGER.debug(\"Ignoring timer of suspended process definition {}\", processDefinition.getId());\n            }\n        } catch (RuntimeException e) {\n            LOGGER.error(\"exception during timer execution\", e);\n            throw e;\n        } catch (Exception e) {\n            LOGGER.error(\"exception during timer execution\", e);\n            throw new ActivitiException(\"exception during timer execution: \" + e.getMessage(), e);\n        }\n    }\n\n    protected void dispatchTimerFiredEvent(Job job, CommandContext commandContext) {\n        if (commandContext.getEventDispatcher().isEnabled()) {\n            commandContext.getEventDispatcher().dispatchEvent(\n                    ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.TIMER_FIRED, job),\n                    EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);\n        }\n    }\n\n}\n","sourceCodeStart":87,"sourceCodeEnd":118,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerStartEventJobHandler.java#L87-L118","documentation":"Same wrapping pattern as TimerExecuteNestedActivityJobHandler: checked Exceptions thrown while starting a new process instance from a timer start event are caught, logged, and rethrown as ActivitiException('exception during timer execution: ' + message). RuntimeExceptions pass through unchanged. The meaningful cause is the wrapped exception.","triggerScenarios":"A checked Exception occurs during startProcessDefinitionByKey execution after the definition lookup succeeded — e.g. while dispatching the TIMER_FIRED event or while starting the process instance (startProcessInstanceByKey path).","commonSituations":"Event dispatcher listeners throwing checked exceptions; failures instantiating the process instance (missing start form variables, delegate initialization errors); environment/classpath problems in the async executor thread.","solutions":["Inspect exception.getCause() and the log entry 'exception during timer execution' for the root cause; fix that first","Check whether custom FlowableEventListener implementations on the event dispatcher throw checked exceptions and wrap them in FlowableException","Verify the async executor's classpath includes all delegates/listeners used by the timer-started process","Retry the job after the fix (managementService or reset retries) since the timer start will re-fire on schedule anyway"],"exampleFix":"// before: listener throws checked exception during TIMER_FIRED dispatch\npublic void onEvent(FlowableEvent event) throws Exception { send(event); }\n// after\npublic void onEvent(FlowableEvent event) {\n  try { send(event); } catch (IOException e) { throw new FlowableException(\"dispatch failed\", e); }\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check that the timer-started process can be instantiated\nProcessDefinition pd = repositoryService.createProcessDefinitionQuery()\n    .processDefinitionKey(key).latestVersion().singleResult();\nif (pd == null || pd.isSuspended()) throw new IllegalStateException(\"definition not startable: \" + key);","typeGuard":null,"tryCatchPattern":"try {\n  managementService.executeJob(startTimerJobId);\n} catch (FlowableException e) {\n  Throwable root = e; while (root.getCause() != null) root = root.getCause();\n  log.error(\"timer start execution failed, root: {}\", root.getMessage(), root);\n}","preventionTips":["Wrap checked exceptions in event listeners/delegates with FlowableException","Test timer-start processes in CI by triggering the job manually (managementService.executeJob)","Keep engine versions consistent across cluster nodes","Monitor the deadletter/failed-job table for timer jobs with this exception"],"tags":["timer-start-event","wrapped-exception","job-executor"],"backgroundTag":"internal-invariant-violation","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"}