flowable/flowable-engine · error · ActivitiIllegalArgumentException
Invalid historic task id : null
Error message
Invalid historic task id : null
What it means
findHistoricTaskInstanceById requires a non-null task id and fails fast with ActivitiIllegalArgumentException otherwise. It validates arguments before hitting the database and also returns null (rather than throwing) when history is disabled.
Solutions
- Ensure the taskId is non-null before calling; fail early in your own code with a clear message.
- Null-check optional inputs (e.g., from HTTP params) before querying history.
- If the id may legitimately be absent, guard with an existence query first.
Example fix
// before
HistoricTaskInstance t = historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult();
// after
if (id == null) throw new IllegalArgumentException("historic task id required");
HistoricTaskInstance t = historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult(); Defensive patterns
Strategy: validation
Validate before calling
if (taskId == null || taskId.isBlank()) {
throw new IllegalArgumentException("historic task id required");
} Type guard
function hasHistoricTaskId(params) {
return typeof params.taskId === 'string' && params.taskId.length > 0;
} Try / catch
try {
return historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
} catch (ActivitiIllegalArgumentException e) {
return null; // or rethrow with your own message
} Prevention
- Validate request/path parameters before querying history
- Don't propagate null ids from earlier lookups
- Check isHistoryEnabled when historic data is optional
When it happens
Trigger: Calling HistoryService.createHistoricTaskInstanceQuery()... or the entity manager method with a null taskId; passing a variable that was never initialized; binding an optional path/request parameter that is missing.
Common situations: REST handlers that don't validate the id parameter; code paths after a task lookup returned null and the null was propagated; unit tests exercising historic queries with placeholder nulls.
Related errors
- caseInstanceId is null
- processInstanceId is null
- processInstanceIds is null
- taskId is null
- appDefinitionId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a433cb8d98c03572.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricTaskInstanceEntityManager.java:99
if (firstResult > 0) {
if (firstResult <= instanceList.size()) {
int toIndex = firstResult + Math.min(maxResults, instanceList.size() - firstResult);
return instanceList.subList(firstResult, toIndex);
} else {
return Collections.EMPTY_LIST;
}
} else {
int toIndex = Math.min(maxResults, instanceList.size());
return instanceList.subList(0, toIndex);
}
}
}
return Collections.EMPTY_LIST;
}
public HistoricTaskInstanceEntity findHistoricTaskInstanceById(String taskId) {
if (taskId == null) {
throw new ActivitiIllegalArgumentException("Invalid historic task id : null");
}
if (getHistoryManager().isHistoryEnabled()) {
return (HistoricTaskInstanceEntity) getDbSqlSession().selectOne("selectHistoricTaskInstance", taskId);
}
return null;
}
@SuppressWarnings("unchecked")
public List<HistoricTaskInstance> findHistoricTasksByParentTaskId(String parentTaskId) {
return getDbSqlSession().selectList("selectHistoricTasksByParentTaskId", parentTaskId);
}
public void deleteHistoricTaskInstanceById(String taskId) {
if (getHistoryManager().isHistoryEnabled()) {
HistoricTaskInstanceEntity historicTaskInstance = findHistoricTaskInstanceById(taskId);
if (historicTaskInstance != null) {
CommandContext commandContext = Context.getCommandContext();
View on GitHub (pinned to d6d39ce1c6)