{"record":{"id":"0b5d2cdefce24071","repo":"OrchardCMS/OrchardCore","slug":"the-updatecontenttask-can-t-update-the-content-item-as-it-is-0b5d2c","errorCode":null,"errorMessage":"The 'UpdateContentTask' can't update the content item as it is executed inline from a starting 'ContentDraftSavedEvent' 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 'ContentDraftSavedEvent' 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":122,"sourceCode":"        {\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        }\n\n        if (!inlineEventOfSameContentItemId)\n        {\n            await ContentManager.UpdateAsync(contentItem);\n        }\n\n        var result = await ContentManager.ValidateAsync(contentItem);\n\n        if (result.Succeeded)\n        {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/UpdateContentTask.cs#L104-L140","documentation":"UpdateContentTask refuses to update (save draft) a content item when executed inline from a ContentDraftSavedEvent workflow of the same content type. Saving a draft within that draft-saved event would re-fire the event recursively, so the task throws InvalidOperationException up front.","triggerScenarios":"A workflow starts with a ContentDraftSavedEvent activity for a content type and its UpdateContentTask has Publish=false; executing the task inline saves a draft, re-triggering the same event.","commonSituations":"Developer wires a 'modify on save' automation (e.g. normalizing fields on every draft save) and keeps the default Publish=false, causing the task to loop against the very event that started it.","solutions":["Set Publish=true on the UpdateContentTask so it publishes rather than re-saving a draft.","Remove the ContentDraftSavedEvent start activity or restrict its content type filter.","Move the update logic into a handler (e.g. ContentHandler updating during Saving) instead of a workflow.","Trigger the workflow from a different event type that the update operation does not raise."],"exampleFix":"// before: UpdateContentTask with Publish = false inside a ContentDraftSavedEvent workflow\n// after\n// In the workflow editor set UpdateContentTask.Publish = true,\n// or replace the UpdateContentTask with a content handler that mutates the item before save.","handlingStrategy":"validation","validationCode":"bool wouldLoop = !task.Publish && inlineEvent.Name == nameof(ContentDraftSavedEvent);\nif (wouldLoop) throw new InvalidOperationException(\"Set Publish=true or change the start event.\");","typeGuard":null,"tryCatchPattern":"try { await workflowManager.RunWorkflowAsync(...); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"UpdateContentTask\")) { logger.LogWarning(ex, \"Inline draft-save loop blocked\"); }","preventionTips":["Never leave Publish=false on UpdateContentTask inside a ContentDraftSavedEvent workflow.","Use content handlers for field mutations during save instead of workflows.","Test workflows against the exact content type they filter on."],"tags":["workflows","infinite-loop","content"],"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"}