{"record":{"id":"8ac8db8dcaf99f2e","repo":"OrchardCMS/OrchardCore","slug":"the-unpublishcontenttask-can-t-unpublish-the-content-item-as","errorCode":null,"errorMessage":"The 'UnpublishContentTask' can't unpublish the content item as it is executed inline from a starting 'ContentUnpublishedEvent' of the same content type, which would result in an infinitive loop.","messagePattern":"The 'UnpublishContentTask' can't unpublish the content item as it is executed inline from a starting 'ContentUnpublishedEvent' 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/UnpublishContentTask.cs","lineNumber":53,"sourceCode":"        {\n            return Outcome(\"Noop\");\n        }\n\n        var contentItem = await ContentManager.GetAsync(content.ContentItem.ContentItemId, VersionOptions.Latest);\n\n        if (contentItem == null)\n        {\n            if (content is ContentItemIdExpressionResult)\n            {\n                throw new InvalidOperationException($\"The '{nameof(UnpublishContentTask)}' failed to retrieve the content item.\");\n            }\n\n            contentItem = content.ContentItem;\n        }\n\n        if (InlineEvent.IsStart && InlineEvent.ContentType == contentItem.ContentType && InlineEvent.Name == nameof(ContentUnpublishedEvent))\n        {\n            throw new InvalidOperationException($\"The '{nameof(UnpublishContentTask)}' can't unpublish the content item as it is executed inline from a starting '{nameof(ContentUnpublishedEvent)}' of the same content type, which would result in an infinitive loop.\");\n        }\n\n        await ContentManager.UnpublishAsync(contentItem);\n\n        return Outcome(\"Unpublished\");\n    }\n}\n","sourceCodeStart":35,"sourceCodeEnd":61,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Activities/UnpublishContentTask.cs#L35-L61","documentation":"This guard prevents an infinite republish/unpublish loop: when UnpublishContentTask runs inline (same request) as the starting ContentUnpublishedEvent of the same content type, unpublishing again would re-trigger the same workflow endlessly. The library throws InvalidOperationException to break the cycle.","triggerScenarios":"Workflow started by a ContentUnpublishedEvent (IsStart) whose content type equals the content item being unpublished, executing inline in the same unpublish operation.","commonSituations":"Developer builds a workflow that reacts to 'Content Unpublished' and itself calls Unpublish on items of the same type (e.g. cascading cleanup over the same type).","solutions":["Use a different starting event triggered earlier in the lifecycle (e.g. ContentDraftSavedEvent) or a non-starting event.","Restrict the event's content type filter so it does not match the type the task unpublishes.","Call UnpublishAsync on a different content item type, or restructure using a separate workflow invocation that is not inline.","Use a LoopBack/condition to prevent re-entry on the same content item."],"exampleFix":"// before\nStart: ContentUnpublishedEvent (ContentType: Article) -> UnpublishContentTask (same Article item)\n// after\nStart: ContentUnpublishedEvent (ContentType: Article) -> Condition (ItemId != source) -> UnpublishContentTask","handlingStrategy":"validation","validationCode":"if (inlineEvent.IsStart && inlineEvent.ContentType == targetItem.ContentType && inlineEvent.Name == nameof(ContentUnpublishedEvent))\n    throw new InvalidOperationException(\"Refusing to unpublish: would re-enter the starting ContentUnpublishedEvent 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 unpublish loop prevented.\");\n}","preventionTips":["Never start a workflow on ContentUnpublishedEvent and unpublish the same content type inline.","Add an event filter or item-ID condition to break re-entrancy.","Model cascading unpublishes as separate workflow executions.","Understand inline vs. queued event execution when designing workflows."],"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"}