{"record":{"id":"05f9d84fa8be2b3e","repo":"flowable/flowable-engine","slug":"error-while-firing-timer-intermediate-event-activ","errorCode":null,"errorMessage":"Error while firing timer: intermediate event activity ${nestedActivityId} not found","messagePattern":"Error while firing timer: intermediate event activity (.+?) not found","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerCatchIntermediateEventJobHandler.java","lineNumber":46,"sourceCode":"\n    private static final Logger LOGGER = LoggerFactory.getLogger(TimerCatchIntermediateEventJobHandler.class);\n\n    public static final String TYPE = \"timer-intermediate-transition\";\n\n    @Override\n    public String getType() {\n        return TYPE;\n    }\n\n    @Override\n    public void execute(Job job, String configuration, ExecutionEntity execution, CommandContext commandContext) {\n\n        String nestedActivityId = TimerEventHandler.getActivityIdFromConfiguration(configuration);\n\n        ActivityImpl intermediateEventActivity = execution.getProcessDefinition().findActivity(nestedActivityId);\n\n        if (intermediateEventActivity == null) {\n            throw new ActivitiException(\"Error while firing timer: intermediate event activity \" + nestedActivityId + \" not found\");\n        }\n\n        try {\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            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;","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerCatchIntermediateEventJobHandler.java#L28-L64","documentation":"TimerCatchIntermediateEventJobHandler.execute extracts the nested activity id from the timer job configuration and resolves it against the process definition. If the activity no longer exists, the engine throws this ActivitiException because the timer fired for an activity that cannot be found to continue execution.","triggerScenarios":"An intermediate-catch timer job fires after its process definition was redeployed/changed so the configured activityId no longer exists, or the job's configuration string points to a wrong activity id.","commonSituations":"Redeploying a new version of the process while old timer jobs still reference old activity ids; manual DB edits of job configuration; deleted/renamed boundary or intermediateCatchEvent ids; running stale jobs after migration.","solutions":["Delete the stale timer jobs referencing the old process definition version","Fix the activity id in the job configuration to an existing activity","Ensure process redeployments migrate or cancel pending timer jobs (e.g. with the process instance migration APIs)","Keep activity ids stable across BPMN edits"],"exampleFix":"// remove stale job for an old definition version\nmanagementService.createTimerJobQuery().processDefinitionId(\"oldDefId\").list()\n  .forEach(j -> managementService.deleteTimerJob(j.getId()));","handlingStrategy":"try-catch","validationCode":"Activity act = repositoryService.createProcessDefinitionQuery()\n    .processDefinitionId(job.getProcessDefinitionId()).singleResult() != null\n    ? null : null; // verify the referenced activityId exists in the definition's BPMN before firing\nString activityId = TimerEventHandler.getActivityIdFromConfiguration(job.getConfiguration());\nif (!bpmnModel.getMainProcess().getFlowElement(activityId, true) ... ) { /* stale job */ }","typeGuard":null,"tryCatchPattern":"try {\n    managementService.moveDeadLetterJobToExecutableJob(jobId, retries);\n} catch (FlowableException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"not found\")) {\n        managementService.deleteTimerJob(staleJobId); // stale definition reference\n    } else throw e;\n}","preventionTips":["Keep activity ids stable across redeployments","Cancel or migrate pending timers when deploying new process versions","Avoid editing job configuration rows directly"],"tags":["timer","jobs","process-definition"],"backgroundTag":"entity-not-found","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"}