OrchardCMS/OrchardCore · error · InvalidOperationException
The 'CreateContentTask' can't create the content item as it…
Error message
The 'CreateContentTask' can't create the content item as it is executed inline from a starting 'ContentCreatedEvent' of the same content type, which would result in an infinitive loop.
What it means
CreateContentTask.ExecuteAsync throws this InvalidOperationException when the workflow runs inline from a starting ContentCreatedEvent whose content type equals the content type the task is configured to create. Creating that content would emit another ContentCreatedEvent inline, re-running the workflow forever. Orchard Core throws instead of allowing the recursion.
Solutions
- Set the CreateContentTask's ContentType to a different type than the starting event's content type.
- If a same-type child item is genuinely needed, disable inline execution for the workflow (run via the non-inline path) and add a guard condition to prevent recursion.
- Split into two content types / use a different triggering event such as ContentPublishedEvent with matching Publish flag.
- Wrap workflow execution in host code that catches InvalidOperationException for this guard and logs it.
Example fix
// before
// Trigger: ContentCreatedEvent { ContentType: "Invoice" }, Task: CreateContentTask { ContentType: "Invoice" }
// after
// Task: CreateContentTask { ContentType: "InvoiceReceipt" } // distinct type breaks the loop Defensive patterns
Strategy: validation
Validate before calling
// Validate before triggering
if (triggerEvent == "ContentCreatedEvent" && triggerIsStart &&
string.Equals(triggerContentType, taskContentType, StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("CreateContentTask would recurse: same content type as the ContentCreatedEvent trigger."); Try / catch
try { await workflowManager.TriggerEventAsync(nameof(ContentCreatedEvent), ...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CreateContentTask") && ex.Message.Contains("ContentCreatedEvent"))
{
logger.LogWarning(ex, "Content creation loop prevented; fix task ContentType.");
} Prevention
- Design workflows so the created content type differs from the triggering one (e.g. Order → Invoice).
- If a same-type child is needed, use a non-inline execution path with an explicit recursion flag.
- Review imported recipes for trigger/task content-type collisions.
- Unit test workflow definitions that pair ContentCreatedEvent with CreateContentTask.
When it happens
Trigger: Workflow with a starting ContentCreatedEvent activity (IsStart=true, ContentType = X) containing a CreateContentTask whose ContentType is also X; the workflow is triggered inline during content creation of X.
Common situations: Developer wants 'whenever an Order is created, create an Invoice' but mistakenly sets the task's content type to 'Order' itself; copied workflow definitions between environments; content-type renamed so task and trigger now collide.
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 update 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/c118fee4923c9232.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/CreateContentTask.cs:78
{
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.");
}
}
var contentItem = await ContentManager.NewAsync(ContentType);
if (!string.IsNullOrWhiteSpace(ContentProperties.Expression))
{
var contentProperties = await _expressionEvaluator.EvaluateAsync(ContentProperties, workflowContext, _javaScriptEncoder);View on GitHub (pinned to 4306c0717f)