{"record":{"id":"1a1d10f6123b03d8","repo":"OrchardCMS/OrchardCore","slug":"the-updatecontenttask-can-t-update-the-content-item-as-it-is-1a1d10","errorCode":null,"errorMessage":"The 'UpdateContentTask' 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.","messagePattern":"The 'UpdateContentTask' 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\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/UpdateContentTask.cs","lineNumber":112,"sourceCode":"        if (!inlineEventOfSameContentItemId)\n        {\n            contentItem = await ContentManager.GetAsync(contentItemId, VersionOptions.DraftRequired);\n        }\n        else\n        {\n            contentItem = workflowContext.Input.GetValue<IContent>(ContentEventConstants.ContentItemInputKey)?.ContentItem;\n        }\n\n        if (contentItem == null)\n        {\n            throw new InvalidOperationException($\"The '{nameof(UpdateContentTask)}' failed to retrieve the content item.\");\n        }\n\n        if (!inlineEventOfSameContentItemId && InlineEvent.IsStart && InlineEvent.ContentType == contentItem.ContentType)\n        {\n            if (InlineEvent.Name == nameof(ContentUpdatedEvent))\n            {\n                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.\");\n            }\n\n            if (Publish && InlineEvent.Name == nameof(ContentPublishedEvent))\n            {\n                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.\");\n            }\n\n            if (!Publish && InlineEvent.Name == nameof(ContentDraftSavedEvent))\n            {\n                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.\");\n            }\n        }\n\n        if (!string.IsNullOrWhiteSpace(ContentProperties.Expression))\n        {\n            var contentProperties = await _expressionEvaluator.EvaluateAsync(ContentProperties, workflowContext, _javaScriptEncoder);\n            contentItem.Merge(JsonNode.Parse(contentProperties), new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Replace });\n        }","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/UpdateContentTask.cs#L94-L130","documentation":"Loop guard for ContentUpdatedEvent: when UpdateContentTask runs inline from a starting ContentUpdatedEvent whose content type matches the target item, the update re-fires the event and loops forever. InvalidOperationException aborts execution to prevent the infinite cycle.","triggerScenarios":"!inlineEventOfSameContentItemId && InlineEvent.IsStart && InlineEvent.ContentType == contentItem.ContentType && InlineEvent.Name == 'ContentUpdatedEvent'.","commonSituations":"Workflow started on 'Content Updated' for type X that itself updates items of type X; each update re-triggers the workflow.","solutions":["Start from an earlier event (e.g. ContentDraftSavedEvent) or a non-starting variant.","Change the event's content type filter so it excludes the updated type.","Update items of a different content type than the trigger.","Restructure the mutation in a content handler before the event fires, or invoke a separate workflow execution."],"exampleFix":"// before\nStart: ContentUpdatedEvent (ContentType: Page) -> UpdateContentTask (Page item, Publish)\n// after\nStart: ContentDraftSavedEvent (ContentType: Page) -> UpdateContentTask (Page item)","handlingStrategy":"validation","validationCode":"if (!sameItemInline && inlineEvent.IsStart && inlineEvent.ContentType == targetItem.ContentType && inlineEvent.Name == nameof(ContentUpdatedEvent))\n    throw new InvalidOperationException(\"UpdateContentTask would re-enter the starting ContentUpdatedEvent of the same type.\");","typeGuard":null,"tryCatchPattern":"try { await task.ExecuteAsync(workflowContext, activityContext); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"infinitive loop\"))\n{\n    logger.LogWarning(ex, \"Inline update loop prevented for ContentUpdatedEvent.\");\n}","preventionTips":["Never start a workflow on ContentUpdatedEvent and update the same content type inline.","Add a content-type or item-ID filter to break re-entrancy.","Use earlier-lifecycle events (ContentDraftSavedEvent) for same-type updates.","Move same-item mutations into content handlers where possible."],"tags":["workflows","content","infinite-loop","recursion"],"backgroundTag":"invalid-state-transition","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}