{"record":{"id":"bab3171ea1962865","repo":"flowable/flowable-engine","slug":"exception-during-timer-execution-message","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/TimerCatchIntermediateEventJobHandler.java","lineNumber":69,"sourceCode":"                commandContext.getEventDispatcher().dispatchEvent(\n                        ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.TIMER_FIRED, job),\n                        EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);\n            }\n\n            if (!execution.getActivity().getId().equals(intermediateEventActivity.getId())) {\n                execution.setActivity(intermediateEventActivity);\n            }\n            execution.signal(null, null);\n        } catch (RuntimeException e) {\n            LogMDC.putMDCExecution(execution);\n            LOGGER.error(\"exception during timer execution\", e);\n            LogMDC.clear();\n            throw e;\n        } catch (Exception e) {\n            LogMDC.putMDCExecution(execution);\n            LOGGER.error(\"exception during timer execution\", e);\n            LogMDC.clear();\n            throw new ActivitiException(\"exception during timer execution: \" + e.getMessage(), e);\n        }\n    }\n\n}\n","sourceCodeStart":51,"sourceCodeEnd":74,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerCatchIntermediateEventJobHandler.java#L51-L74","documentation":"Generic wrapper in TimerCatchIntermediateEventJobHandler.execute: any unexpected Exception while firing the timer (signal/execution continuation, event dispatch, etc.) is logged and rethrown as an ActivitiException whose message is the original exception's message, keeping the cause chain. It is a catch-all so timer failures surface with the underlying reason.","triggerScenarios":"Any runtime exception thrown inside timer execution after the activity lookup succeeded: e.g. failures signaling the execution, event dispatcher errors, or delegate errors triggered during continuation.","commonSituations":"Execution already ended when timer fires (concurrent completion); event dispatcher misconfigured; downstream service task behind the timer fails; DB constraint issue while persisting the continuation.","solutions":["Read the cause of the ActivitiException (getCause()) to find the real failure","Check for concurrent modification: the process instance may have completed/moved past the timer before it fired","Fix the underlying exception reported in the wrapped cause (dispatcher config, delegate, DB)","Enable logging around TIMER_FIRED events to reproduce"],"exampleFix":"try {\n    managementService.executeJob(jobId);\n} catch (FlowableException e) {\n    log.error(\"timer failed\", e.getCause()); // real reason is the cause\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    managementService.executeJob(jobId);\n} catch (FlowableException e) {\n    Throwable root = e; while (root.getCause() != null) root = root.getCause();\n    log.error(\"Timer execution failed, root cause: \", root); // act on the wrapped cause\n}","preventionTips":["Always inspect getCause() — this error only mirrors the inner message","Add retries with backoff for transient DB/concurrency failures during timer firing","Monitor engine logs: the original exception is logged before rethrow"],"tags":["timer","jobs","exception-wrapping"],"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"}