flowable/flowable-engine · error · ActivitiException

exception during timer execution: ${message}

Error message

exception during timer execution: ${message}

What it means

Wrapper thrown when the timer job handler itself throws a checked Exception during execution of the timer's target activity behavior. RuntimeExceptions are rethrown as-is; checked exceptions are wrapped in an ActivitiException with the original message. It indicates the actual timer fire logic (entering the nested activity) failed, e.g. inside a delegate or activity behavior.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerExecuteNestedActivityJobHandler.java:73

        try {
            if (commandContext.getEventDispatcher().isEnabled()) {
                commandContext.getEventDispatcher().dispatchEvent(
                        ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.TIMER_FIRED, job),
                        EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
                dispatchActivityTimeoutIfNeeded(job, execution, commandContext);
            }

            borderEventActivity
                    .getActivityBehavior()
                    .execute(execution);
        } catch (RuntimeException e) {
            LOGGER.error("exception during timer execution", e);
            throw e;

        } catch (Exception e) {
            LOGGER.error("exception during timer execution", e);
            throw new ActivitiException("exception during timer execution: " + e.getMessage(), e);
        }
    }

    protected void dispatchActivityTimeoutIfNeeded(Job timerEntity, ExecutionEntity execution, CommandContext commandContext) {

        String nestedActivityId = TimerEventHandler.getActivityIdFromConfiguration(timerEntity.getJobHandlerConfiguration());

        ActivityImpl boundaryEventActivity = execution.getProcessDefinition().findActivity(nestedActivityId);
        ActivityBehavior boundaryActivityBehavior = boundaryEventActivity.getActivityBehavior();
        if (boundaryActivityBehavior instanceof BoundaryEventActivityBehavior) {
            BoundaryEventActivityBehavior boundaryEventActivityBehavior = (BoundaryEventActivityBehavior) boundaryActivityBehavior;
            if (boundaryEventActivityBehavior.isInterrupting()) {
                dispatchExecutionTimeOut(timerEntity, execution, commandContext);
            }
        }
    }

    protected void dispatchExecutionTimeOut(Job job, ExecutionEntity execution, CommandContext commandContext) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Read the wrapped cause (e.getCause()) — the root exception identifies the real failure; fix that root cause first
  2. Check the server log for the preceding 'exception during timer execution' LOGGER.error entry with the full stack trace
  3. If caused by a delegate/listener, convert checked exceptions to FlowableException/BpmnError or handle them inside the delegate
  4. After fixing, retry the job via managementService or by resetting retries on the failed job

Example fix

// before: delegate throws checked exception
public void execute(DelegateExecution execution) throws Exception {
  Files.copy(src, dst); // checked IOException bubbles into ActivitiException
}
// after
public void execute(DelegateExecution execution) {
  try { Files.copy(src, dst); }
  catch (IOException e) { throw new FlowableException("copy failed", e); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the timer target activity and its delegates are present before firing
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
    .processDefinitionId(defId).singleResult();
if (pd == null) throw new IllegalStateException("definition missing for timer job");
BpmnModel model = repositoryService.getBpmnModel(defId);
if (model.getFlowElement(activityId) == null) throw new IllegalStateException("activity " + activityId + " missing");

Try / catch

try {
  managementService.executeJob(timerJobId);
} catch (FlowableException e) {
  Throwable root = e; while (root.getCause() != null) root = root.getCause();
  log.error("timer execution failed, root cause: {}", root.getMessage(), root);
  managementService.setJobRetries(timerJobId, 1); // let it fail definitively after inspection
}

Prevention

When it happens

Trigger: Any checked Exception thrown while executing TimerExecuteNestedActivityJobHandler.execute — typically from the activity behavior invoked when the timer fires (TimerCatchIntermediateEventActivityBehavior / boundary event behavior) or from event dispatching code.

Common situations: A custom JavaDelegate or listener on the timer target activity throws a checked exception; IO failures during event dispatch; classpath issues loading activity behavior classes in a different deployment context.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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