elsa-workflows/elsa-core · error · InvalidOperationException
Runtime entity definition
Error message
Runtime entity definition '{definition.Name}' is not published. What it means
SaveInstanceAsync requires the referenced definition to be in Published status; Draft or Retired definitions reject writes. When the definition exists but its Status differs from Published, the manager throws InvalidOperationException naming the definition.
Solutions
- Call PublishAsync(definitionName) to move the definition to Published before saving instances.
- If the definition was retired, publish a new version and update writers to use it.
- Check definition.Status via GetDefinitionAsync in orchestration code and skip/park instance writes while not Published.
Example fix
// before await manager.SaveDraftAsync(definition); await manager.SaveInstanceAsync(instance); // throws: not published // after await manager.SaveDraftAsync(definition); await manager.PublishAsync(definition.Name); await manager.SaveInstanceAsync(instance);
Defensive patterns
Strategy: validation
Validate before calling
var def = await manager.GetDefinitionAsync(instance.DefinitionName);
if (def is not null && def.Status != RuntimeEntityDefinitionStatus.Published)
throw new InvalidOperationException($"Definition '{def.Name}' must be Published before saving instances."); Try / catch
try { await manager.SaveInstanceAsync(instance); }
catch (InvalidOperationException ex) when (ex.Message.Contains("is not published")) { /* publish definition or queue the write */ } Prevention
- Make PublishAsync part of the definition deployment pipeline, never draft-only.
- When retiring definitions, first stop or migrate all instance writers.
- Assert definition.Status == Published in test fixtures before data seeding.
When it happens
Trigger: Saving an instance while the definition is still Draft (SaveDraftAsync without PublishAsync), or after RetireAsync was called for the definition.
Common situations: Forgetting the publish step after editing a definition; retiring an old definition while background jobs still write instances; seeding data against a freshly created draft in tests.
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
- No declared index exists for storage unit
- Runtime entity definition
- Runtime entity definition document
- Runtime entity definition
- Runtime entity definition
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/2552314d6b5ec2ea.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityManager.cs:73
var existing = await LoadDefinitionDocumentAsync(name, cancellationToken)
?? throw new InvalidOperationException($"Runtime entity definition '{name}' was not found.");
existing.Definition.Status = RuntimeEntityDefinitionStatus.Retired;
existing.Definition.UpdatedAt = DateTimeOffset.UtcNow;
await SaveDefinitionAsync(existing.Definition, existing.Document.Version, cancellationToken);
await AppendAuditAsync("RuntimeEntityDefinition", existing.Definition.Name, "Retired", $"Version {existing.Definition.Version} retired.", cancellationToken);
return existing.Definition;
}
public async Task<RuntimeEntityInstance> SaveInstanceAsync(RuntimeEntityInstance instance, CancellationToken cancellationToken = default)
{
instance.DefinitionName = NormalizeName(instance.DefinitionName);
var definition = await GetDefinitionAsync(instance.DefinitionName, cancellationToken)
?? throw new InvalidOperationException($"Runtime entity definition '{instance.DefinitionName}' was not found.");
if (definition.Status != RuntimeEntityDefinitionStatus.Published)
throw new InvalidOperationException($"Runtime entity definition '{definition.Name}' is not published.");
validator.ValidateInstance(definition, instance);
instance.DefinitionVersion = definition.Version;
var existing = await LoadInstanceDocumentAsync(instance.DefinitionName, instance.Id, cancellationToken);
var now = DateTimeOffset.UtcNow;
instance.CreatedAt = existing?.Instance.CreatedAt ?? instance.CreatedAt;
instance.UpdatedAt = now;
var request = new SaveDocumentRequest(
RuntimeEntityPersistenceSchemaProvider.InstancesStorageUnit,
CreateInstanceDocumentId(instance.DefinitionName, instance.Id),
JsonSerializer.Serialize(instance, _jsonOptions),
CreateInstanceIndexValues(definition, instance),
existing?.Document.Version ?? 0);
await documentStore.SaveAsync(request, cancellationToken);
await AppendAuditAsync("RuntimeEntityInstance", CreateInstanceDocumentId(instance.DefinitionName, instance.Id), existing is null ? "Created" : "Updated", null, cancellationToken);View on GitHub (pinned to fe9217bdfa)