flowable/flowable-engine · error · RuntimeException
Operation is not supported
Error message
Operation is not supported
What it means
BaseHistoricTaskLogEntryBuilderImpl is the base builder for historic task log entries; its create() method is intentionally unsupported — concrete subclasses are expected to implement persistence. Calling create() directly on the base builder (or a subclass that does not override it) always throws this RuntimeException with the message 'Operation is not supported'.
Solutions
- Use the public API builder (taskService.createHistoricTaskLogEntryBuilder(taskId)) which returns a fully functional implementation, not the base impl class.
- If you subclass BaseHistoricTaskLogEntryBuilderImpl, override create() to execute the persistence command via the CommandExecutor.
- Check imports — reference the interface HistoricTaskLogEntryBuilder, not BaseHistoricTaskLogEntryBuilderImpl, so the right implementation is used.
Example fix
// before
BaseHistoricTaskLogEntryBuilderImpl builder = new BaseHistoricTaskLogEntryBuilderImpl();
builder.create(); // RuntimeException: Operation is not supported
// after
HistoricTaskLogEntryBuilder builder =
taskService.createHistoricTaskLogEntryBuilder(taskId)
.type(HistoricTaskLogEntryType.USER_MODIFIED)
.data("field", "assignee");
builder.create(); // persists via the concrete implementation Defensive patterns
Strategy: try-catch
Validate before calling
if (builder instanceof BaseHistoricTaskLogEntryBuilderImpl) {
throw new IllegalStateException("Use taskService.createHistoricTaskLogEntryBuilder instead of the base impl class");
} Try / catch
try {
builder.create();
} catch (RuntimeException e) {
if ("Operation is not supported".equals(e.getMessage())) {
// switch to the concrete service-provided builder
}
} Prevention
- Always obtain the builder from TaskService public API, not by instantiating impl classes
- Program against the HistoricTaskLogEntryBuilder interface
- When subclassing the base impl, always override create()
When it happens
Trigger: Calling create() on a HistoricTaskLogEntryBuilder obtained as BaseHistoricTaskLogEntryImpl's default builder (e.g. taskService.getBaseHistoricTaskLogEntryBuilder() or a subclass that didn't override create()), instead of a concrete implementation wired to a CommandExecutor.
Common situations: Using an internal builder implementation directly because of an import/refactor to the impl package; custom subclass of BaseHistoricTaskLogEntryBuilderImpl that forgot to override create(); upgrading Flowable where the default create() changed to throw.
Related errors
- CaseMigrationService cannot be null, Obtain your builder…
- Function Delegate has more than one function method
- Function has more than one local name
- Outbound processor should never call this
- A resource name is mandatory
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a7e52178c035c39e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/BaseHistoricTaskLogEntryBuilderImpl.java:201
@Override
public String getSubScopeId() {
return subScopeId;
}
@Override
public String getScopeType() {
return scopeType;
}
@Override
public String getTenantId() {
return tenantId;
}
@Override
public void create() {
// add is not supported by default
throw new RuntimeException("Operation is not supported");
}
}
View on GitHub (pinned to d6d39ce1c6)