elsa-workflows/elsa-core · error · InvalidOperationException
Cannot retract an unpublished workflow definition.
Error message
Cannot retract an unpublished workflow definition.
What it means
WorkflowDefinitionPublisher.RetractAsync only supports retracting definitions that are currently published. Attempting to retract an unpublished (draft or never-published) definition throws InvalidOperationException because retraction is meaningless without a published version.
Solutions
- Check definition.IsPublished before calling RetractAsync and skip the call when false.
- Re-fetch the definition from the store immediately before retracting to get the current publish state.
- If the intent is to delete the draft instead, use the definition deletion API rather than retract.
Example fix
// before
await publisher.RetractAsync(definition);
// after
if (definition.IsPublished)
await publisher.RetractAsync(definition); Defensive patterns
Strategy: validation
Validate before calling
if (!definition.IsPublished) throw new InvalidOperationException($"Definition {definition.DefinitionId} is not published; nothing to retract."); Try / catch
try { await publisher.RetractAsync(definition); } catch (InvalidOperationException) { /* already unpublished; treat as no-op */ } Prevention
- Always check IsPublished before retracting
- Re-read the definition from the store before state transitions
- Guard against duplicate retract requests with idempotency handling
- Handle retraction results from concurrent users gracefully
When it happens
Trigger: Calling IWorkflowDefinitionPublisher.RetractAsync with a WorkflowDefinition whose IsPublished is false — e.g. a fresh draft, an already-retracted definition, or an instance loaded from a store where the published flag was cleared.
Common situations: Double-retraction after a retry; retracting by ID where the definition was already retracted by another user/process; a race where the definition was unpublished between check and call.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- A workflow definition already exists for definition
- Activity context is not a flowchart.
- BPMN element ' ' binds process activity ' ' as the work of…
- Invalid variable test values.
- No published version of workflow definition with ID
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/0c60dc5a43603d41.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionPublisher.cs:144
}
/// <inheritdoc />
public async Task<WorkflowDefinition?> RetractAsync(string definitionId, CancellationToken cancellationToken = default)
{
var filter = WorkflowDefinitionHandle.ByDefinitionId(definitionId, VersionOptions.Published).ToFilter();
var definition = await workflowDefinitionStore.FindAsync(filter, cancellationToken);
if (definition == null)
return null;
return await RetractAsync(definition, cancellationToken);
}
/// <inheritdoc />
public async Task<WorkflowDefinition> RetractAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default)
{
if (!definition.IsPublished)
throw new InvalidOperationException("Cannot retract an unpublished workflow definition.");
definition.IsPublished = false;
await mediator.SendAsync(new WorkflowDefinitionRetracting(definition), cancellationToken);
await workflowDefinitionStore.SaveAsync(definition, cancellationToken);
await mediator.SendAsync(new WorkflowDefinitionRetracted(definition), cancellationToken);
return definition;
}
public async Task<WorkflowDefinition> RevertVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default)
{
var latestVersionFilter = new WorkflowDefinitionFilter
{
DefinitionId = definitionId,
VersionOptions = VersionOptions.Latest
};
var latestVersion = await workflowDefinitionStore.FindAsync(latestVersionFilter, cancellationToken);
var lastVersionFilter = new WorkflowDefinitionFilterView on GitHub (pinned to fe9217bdfa)