OrchardCMS/OrchardCore · error · InvalidOperationException
The 'UpdateContentTask' can't publish the content item as…
Error message
The 'UpdateContentTask' can't publish the content item as it is executed inline from a starting 'ContentPublishedEvent' of the same content type, which would result in an infinitive loop.
What it means
UpdateContentTask refuses to publish a content item when it is executed inline from a ContentPublishedEvent workflow started for the same content type. Re-publishing inside the publish event would re-trigger the same workflow, producing an infinite loop. The guard throws InvalidOperationException before any content is modified.
Solutions
- Uncheck Publish on the UpdateContentTask so it saves a draft instead of re-publishing.
- Remove the ContentPublishedEvent start activity or scope it to a different content type.
- Set the inline event's content type filter so the workflow does not match the type being updated.
- Use a non-inline trigger (e.g. a scheduled/background workflow) if the re-publish is genuinely required.
Example fix
// before: UpdateContentTask with Publish = true inside a ContentPublishedEvent workflow // after // In the workflow editor set UpdateContentTask.Publish = false (save draft only), // or start the workflow from ContentDraftSavedEvent with Publish = true instead.
Defensive patterns
Strategy: validation
Validate before calling
// In the workflow editor, before enabling:
bool wouldLoop = task.Publish && inlineEvent.Name == nameof(ContentPublishedEvent);
if (wouldLoop) throw new InvalidOperationException("Set Publish=false or change the start event."); Try / catch
try { await workflowManager.RunWorkflowAsync(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("UpdateContentTask")) { logger.LogWarning(ex, "Inline publish loop blocked"); } Prevention
- Never leave Publish=true on UpdateContentTask inside a ContentPublishedEvent workflow.
- Prefer saving drafts for updates triggered by publish events.
- Review workflow definitions after upgrades to Orchard Core versions that added these loop guards.
When it happens
Trigger: A workflow starts with a ContentPublishedEvent activity for a content type, and the workflow's UpdateContentTask has Publish=true; the task runs inline during the same publish request and tries to publish the item again.
Common situations: Developer builds an automation that 'touches' content on publish (e.g. updating a date or computed field) and leaves the Publish checkbox enabled on the UpdateContentTask, not realizing publishing re-enters the same workflow.
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
- The 'UnpublishContentTask' can't unpublish the content item…
- The 'UpdateContentTask' can't update the content item as it…
- The 'UpdateContentTask' can't update the content item as it…
- The 'UpdateContentTask' can't update the content item as it…
- The 'UpdateContentTask' can't update the content item as it…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/01ad316b7202a0c2.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/UpdateContentTask.cs:117
{
contentItem = workflowContext.Input.GetValue<IContent>(ContentEventConstants.ContentItemInputKey)?.ContentItem;
}
if (contentItem == null)
{
throw new InvalidOperationException($"The '{nameof(UpdateContentTask)}' failed to retrieve the content item.");
}
if (!inlineEventOfSameContentItemId && InlineEvent.IsStart && InlineEvent.ContentType == contentItem.ContentType)
{
if (InlineEvent.Name == nameof(ContentUpdatedEvent))
{
throw new InvalidOperationException($"The '{nameof(UpdateContentTask)}' can't update the content item as it is executed inline from a starting '{nameof(ContentUpdatedEvent)}' of the same content type, which would result in an infinitive loop.");
}
if (Publish && InlineEvent.Name == nameof(ContentPublishedEvent))
{
throw new InvalidOperationException($"The '{nameof(UpdateContentTask)}' can't publish the content item as it is executed inline from a starting '{nameof(ContentPublishedEvent)}' of the same content type, which would result in an infinitive loop.");
}
if (!Publish && InlineEvent.Name == nameof(ContentDraftSavedEvent))
{
throw new InvalidOperationException($"The '{nameof(UpdateContentTask)}' can't update the content item as it is executed inline from a starting '{nameof(ContentDraftSavedEvent)}' of the same content type, which would result in an infinitive loop.");
}
}
if (!string.IsNullOrWhiteSpace(ContentProperties.Expression))
{
var contentProperties = await _expressionEvaluator.EvaluateAsync(ContentProperties, workflowContext, _javaScriptEncoder);
contentItem.Merge(JsonNode.Parse(contentProperties), new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Replace });
}
if (!inlineEventOfSameContentItemId)
{
await ContentManager.UpdateAsync(contentItem);
}View on GitHub (pinned to 4306c0717f)