OrchardCMS/OrchardCore · error · InvalidOperationException
The 'CreateContentTask' can't update the content item as it…
Error message
The 'CreateContentTask' can't update the content item as it is executed inline from a starting 'ContentUpdatedEvent' of the same content type, which would result in an infinitive loop.
What it means
CreateContentTask.ExecuteAsync throws this InvalidOperationException when the workflow was started inline by a ContentUpdatedEvent for the same content type the task would create/update. Because inline workflows run synchronously inside the content event pipeline, creating/updating content of that type would re-trigger the same event, producing an infinite loop. The throw is a deliberate safety guard in Orchard Core Workflows.
Solutions
- Change the CreateContentTask's ContentType to a different content type than the one that starts the workflow.
- Disable the workflow's InlineEvent delivery (configure the workflow to run non-inline/queued) so the loop guard is not engaged, and add a loop-avoidance condition instead.
- Use a different starting event (e.g. ContentCreatedEvent or ContentPublishedEvent) that does not conflict with the task's operation.
- Catch InvalidOperationException in custom host code and log/skip the activity run.
Example fix
// before: workflow starts on ContentUpdatedEvent for 'Article', task creates 'Article' ContentType = "Article"; // after: create a distinct audit content type instead ContentType = "ArticleAuditEntry";
Defensive patterns
Strategy: validation
Validate before calling
// Before configuring/saving the workflow
bool loops = triggerEvent == "ContentUpdatedEvent"
&& triggerIsStart
&& string.Equals(triggerContentType, taskContentType, StringComparison.OrdinalIgnoreCase);
if (loops) throw new InvalidOperationException("CreateContentTask ContentType must differ from the starting event's content type."); Try / catch
try { await workflowManager.TriggerEventAsync(nameof(ContentUpdatedEvent), ...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CreateContentTask") && ex.Message.Contains("infinitive loop"))
{
logger.LogWarning(ex, "Workflow loop guard triggered; reconfigure the workflow.");
} Prevention
- Never set a content task's ContentType equal to the content type of the starting content event.
- Prefer non-inline workflow execution when creating the same type in response to its own events.
- Add a condition activity that checks the created item differs from the triggering item.
- Test workflows on a staging tenant where loops surface as this exception instead of hangs.
When it happens
Trigger: A workflow with a starting ContentUpdatedEvent activity (IsStart=true) whose ContentType matches the CreateContentTask's ContentType property, and the task's ContentProperties expression targets the same content type, executed inline (inline event delivery, not the queued/default path).
Common situations: Developer builds a workflow 'when a Page is updated, create/update a related Page' with an inline-starting ContentUpdatedEvent; self-referential content synchronization rules; copying a workflow designed for a different event type onto ContentUpdatedEvent without changing the task's ContentType.
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 'CreateContentTask' can't create the content item as it…
- The 'CreateContentTask' can't publish the content item as…
- The 'CreateContentTask' can't create the content item as it…
- The 'DeleteContentTask' can't delete the content item as it…
- The 'PublishContentTask' can't publish the content item as…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/5c3ac49026486014.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/CreateContentTask.cs:73
get => GetProperty(() => new WorkflowExpression<string>(JConvert.SerializeObject(new { DisplayText = S["Enter a title"].Value }, JOptions.Indented)));
set => SetProperty(value);
}
public override bool CanExecute(WorkflowExecutionContext workflowContext, ActivityContext activityContext)
{
return !string.IsNullOrEmpty(ContentType);
}
public override IEnumerable<Outcome> GetPossibleOutcomes(WorkflowExecutionContext workflowContext, ActivityContext activityContext)
=> Outcome(S["Done"], S["Failed"]);
public override async Task<ActivityExecutionResult> ExecuteAsync(WorkflowExecutionContext workflowContext, ActivityContext activityContext)
{
if (InlineEvent.IsStart && InlineEvent.ContentType == ContentType)
{
if (InlineEvent.Name == nameof(ContentUpdatedEvent))
{
throw new InvalidOperationException($"The '{nameof(CreateContentTask)}' 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 (InlineEvent.Name == nameof(ContentCreatedEvent))
{
throw new InvalidOperationException($"The '{nameof(CreateContentTask)}' can't create the content item as it is executed inline from a starting '{nameof(ContentCreatedEvent)}' of the same content type, which would result in an infinitive loop.");
}
if (Publish && InlineEvent.Name == nameof(ContentPublishedEvent))
{
throw new InvalidOperationException($"The '{nameof(CreateContentTask)}' 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(CreateContentTask)}' can't create 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.");
}
}
View on GitHub (pinned to 4306c0717f)