{"record":{"id":"87b578c25be69567","repo":"flowable/flowable-engine","slug":"could-not-find-process-definition-needed-for-timer-87b578","errorCode":null,"errorMessage":"Could not find process definition needed for timer start event","messagePattern":"Could not find process definition needed for timer start event","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerStartEventJobHandler.java","lineNumber":89,"sourceCode":"            LOGGER.debug(\"Ignoring timer of suspended process definition {}\", processDefinition.getId());\n        }\n\n    }\n\n    protected void startProcessDefinitionByKey(Job job, String configuration, DeploymentManager deploymentManager, CommandContext commandContext) {\n\n        // it says getActivityId, but < 5.21, this would have the process definition key stored\n        String processDefinitionKey = TimerEventHandler.getActivityIdFromConfiguration(configuration);\n\n        ProcessDefinition processDefinition = null;\n        if (job.getTenantId() == null || ProcessEngineConfiguration.NO_TENANT_ID.equals(job.getTenantId())) {\n            processDefinition = deploymentManager.findDeployedLatestProcessDefinitionByKey(processDefinitionKey);\n        } else {\n            processDefinition = deploymentManager.findDeployedLatestProcessDefinitionByKeyAndTenantId(processDefinitionKey, job.getTenantId());\n        }\n\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    }","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerStartEventJobHandler.java#L71-L107","documentation":"TimerStartEventJobHandler throws this when a timer-start job fires but no deployed process definition can be resolved for its processDefinitionKey — neither latest overall nor latest for the job's tenant. The deployment manager returned null from findDeployedLatestProcessDefinitionByKey(ByTenantId).","triggerScenarios":"A timer start event job exists in ACT_RU_JOB for a process definition key whose latest deployed definition was deleted (repositoryService.deleteDeployment without cascade of the key), or the definition was deployed under a different tenantId than the job's tenant.","commonSituations":"Multi-tenant setups where the timer job carries a tenantId but the definition was deployed with no tenant (or vice versa); undeploying/replacing a process while its timer-start job survives; typo in process key between redeploys.","solutions":["Verify a deployed (non-deleted) definition exists: repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).latestVersion().singleResult(); redeploy the BPMN if missing","Check tenant alignment: compare job.getTenantId() (ACT_RU_JOB.TENANT_ID_) with the definition's tenant; redeploy with matching tenant or null-tenant","Delete the orphan timer-start job via managementService.deleteJob if the process is intentionally gone","For time-based start events, confirm the job's PROCESS_DEFINITION_KEY_ matches the bpmn <process id=\"...\">"],"exampleFix":"// before: deployed with tenant but job created without one (or vice versa)\nrepositoryService.createDeployment().addClasspathResource(\"process.bpmn\").tenantId(\"acme\").deploy();\n// after: keep tenant consistent with existing timer jobs\nrepositoryService.createDeployment().addClasspathResource(\"process.bpmn\")\n    .tenantId(jobTenantIdIfAny) // or omit tenantId to match null-tenant jobs\n    .deploy();","handlingStrategy":"validation","validationCode":"ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()\n    .processDefinitionKey(key)\n    .processDefinitionTenantId(tenantId) // match the job's tenant, or omit for null-tenant\n    .latestVersion().singleResult();\nif (pd == null) throw new IllegalStateException(\"timer start key \" + key + \" not deployed for tenant \" + tenantId);","typeGuard":"boolean isDeployed(String key, String tenantId) {\n  ProcessDefinitionQuery q = repositoryService.createProcessDefinitionQuery()\n      .processDefinitionKey(key).latestVersion();\n  return (tenantId != null ? q.processDefinitionTenantId(tenantId) : q)\n      .singleResult() != null;\n}","tryCatchPattern":"try {\n  managementService.executeJob(startTimerJobId);\n} catch (FlowableException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Could not find process definition needed for timer start event\")) {\n    log.error(\"timer start job orphaned for key={}, tenant={}\", key, tenantId);\n    managementService.deleteJob(startTimerJobId);\n  } else { throw e; }\n}","preventionTips":["Deploy the BPMN under the same tenantId used by existing timer jobs","Never delete a deployment holding timer-start jobs without cascade or recreating the schedule afterwards","Keep <process id=\"...\"> stable across redeploys; the job references this key","After undeploying, query and clean leftover timer-start jobs in ACT_RU_JOB"],"tags":["timer-start-event","process-definition","multi-tenancy","job-executor"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}