conductor-oss/conductor · error · UnsupportedOperationException
This method is not currently implemented in CassandraExecuti
Error message
This method is not currently implemented in CassandraExecutionDAO. Please use RedisDAO mode instead now for using TTLs.
What it means
CassandraExecutionDAO.removeWorkflowWithExpiry throws UnsupportedOperationException because TTL-based workflow removal is not implemented on the Cassandra backend (Cassandra does not natively TTL its workflow row in this schema). The DAO is a dummy stub by design; the message points users to the Redis-backed ExecutionDAO, which supports per-row expiry. This is a backend-capability gap, not a transient fault.
Source
Thrown at cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraExecutionDAO.java:490
removed = resultSet.wasApplied();
} catch (DriverException e) {
Monitors.error(CLASS_NAME, "removeWorkflow");
String errorMsg = String.format("Failed to remove workflow: %s", workflowId);
LOGGER.error(errorMsg, e);
throw new TransientException(errorMsg);
}
workflow.getTasks().forEach(this::removeTaskLookup);
}
return removed;
}
/**
* This is a dummy implementation and this feature is not yet implemented for Cassandra backed
* Conductor
*/
@Override
public boolean removeWorkflowWithExpiry(String workflowId, int ttlSeconds) {
throw new UnsupportedOperationException(
"This method is not currently implemented in CassandraExecutionDAO. Please use RedisDAO mode instead now for using TTLs.");
}
/**
* No-op: Cassandra does not maintain a pending-workflows structure, so there is nothing to
* remove. This used to throw UnsupportedOperationException, which turned every
* completeWorkflow/terminateWorkflow call that hits the already-terminal branch into an HTTP
* 500 — the workflow write paths cannot be allowed to fail on a bookkeeping call whose state
* does not exist on this backend.
*/
@Override
public void removeFromPendingWorkflow(String workflowType, String workflowId) {}
@Override
public WorkflowModel getWorkflow(String workflowId) {
return getWorkflow(workflowId, true);
}
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Switch the execution persistence layer to Redis (redis-persistence) if you require TTL-based workflow removal.
- Call removeWorkflow(workflowId, archiveWorkflow) instead of removeWorkflowWithExpiry; Cassandra removes the row immediately without a TTL.
- If you must stay on Cassandra and need expiry, schedule removal externally (a reaper job) rather than relying on the DAO TTL.
- Guard the call site with a check for the concrete DAO type and skip/disable the TTL path on Cassandra.
Example fix
// before
executionDAO.removeWorkflowWithExpiry(workflowId, ttlSeconds);
// after
if (executionDAO instanceof CassandraExecutionDAO) {
executionDAO.removeWorkflow(workflowId); // no TTL on Cassandra
} else {
executionDAO.removeWorkflowWithExpiry(workflowId, ttlSeconds);
} Defensive patterns
Strategy: validation
Validate before calling
// Before requesting TTL-based removal, check the backend capability
boolean supportsExpiry = !(executionDAO instanceof CassandraExecutionDAO);
if (!supportsExpiry) {
LOGGER.warn("TTL removal unsupported on {} — removing immediately",
executionDAO.getClass().getSimpleName());
executionDAOFacade.removeWorkflow(workflowId, false);
} else {
executionDAO.removeWorkflowWithExpiry(workflowId, ttlSeconds);
} Type guard
// capability check for TTL removal
public boolean supportsWorkflowExpiry(ExecutionDAO dao) {
return !(dao instanceof CassandraExecutionDAO);
} Try / catch
try {
executionDAO.removeWorkflowWithExpiry(workflowId, ttlSeconds);
} catch (UnsupportedOperationException e) {
LOGGER.warn("TTL removal unsupported, falling back to immediate remove", e);
executionDAOFacade.removeWorkflow(workflowId, false);
} Prevention
- Prefer ExecutionDAOFacade over the raw CassandraExecutionDAO at all call sites.
- Document which backends support TTL removal when selecting a persistence module.
- Add an integration test that asserts the unsupported path degrades gracefully on Cassandra.
When it happens
Trigger: Calling executionDAO.removeWorkflowWithExpiry(workflowId, ttlSeconds) while the active ExecutionDAO bean is CassandraExecutionDAO. This is reached by code paths (e.g. archival/cleanup) that request a TTL on removal.
Common situations: Selecting the cassandra-persistence module as the execution store (`conductor.cassandra.enabled`) and then enabling a workflow-removal-with-TTL feature, or porting code from a Redis deployment that relied on expiring rows.
Related errors
- Invalid row with entityKey: %s found in datastore for workfl
- Failed to get workflow: %s
- Failed to add event execution for event: %s, handler: %s
- Failed to update event execution for event: %s, handler: %s
- Failed to remove event execution for event: %s, handler: %s
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/2d412a04fb648a51.
Report an issue: GitHub.