{"record":{"id":"f55c6a7595dcfed1","repo":"OrchardCMS/OrchardCore","slug":"the-cloned-content-item-doesn-t-contain-an-autoroutepart","errorCode":null,"errorMessage":"The cloned content item doesn't contain an AutoroutePart.","messagePattern":"The cloned content item doesn't contain an AutoroutePart\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs","lineNumber":151,"sourceCode":"    }\n\n    public override async Task CreatedAsync(CreateContentContext context, AutoroutePart part)\n    {\n        await GenerateContainerPathFromPatternAsync(part);\n        await GenerateContainedPathsFromPatternAsync(context.ContentItem, part);\n    }\n\n    public override async Task UpdatedAsync(UpdateContentContext context, AutoroutePart part)\n    {\n        await GenerateContainerPathFromPatternAsync(part);\n        await GenerateContainedPathsFromPatternAsync(context.ContentItem, part);\n    }\n\n    public override async Task CloningAsync(CloneContentContext context, AutoroutePart part)\n    {\n        if (!context.CloneContentItem.TryGet<AutoroutePart>(out var clonedPart))\n        {\n            throw new InvalidOperationException(\"The cloned content item doesn't contain an AutoroutePart.\");\n        }\n\n        clonedPart.Path = await GenerateUniqueAbsolutePathAsync(part.Path, context.CloneContentItem.ContentItemId);\n        clonedPart.SetHomepage = false;\n        clonedPart.Apply();\n\n        await GenerateContainedPathsFromPatternAsync(context.CloneContentItem, part);\n    }\n\n    public override Task GetContentItemAspectAsync(ContentItemAspectContext context, AutoroutePart part)\n    {\n        return context.ForAsync<RouteHandlerAspect>(async aspect =>\n        {\n            var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);\n            var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, \"AutoroutePart\", StringComparison.Ordinal));\n            var settings = contentTypePartDefinition.GetSettings<AutoroutePartSettings>();\n            if (settings.ManageContainedItemRoutes)\n            {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs#L133-L169","documentation":"AutoroutePartHandler.CloningAsync generates a unique absolute path for the cloned item, but first requires the clone (CloneContentItem) to already carry an AutoroutePart. If the cloned content item lacks that part it throws InvalidOperationException, indicating the clone operation produced an item inconsistent with the source.","triggerScenarios":"Cloning a content item whose type has AutoroutePart attached to the source but where the clone pipeline removed/did not copy the part (e.g. clone created manually without parts, or type definitions changed between source and clone).","commonSituations":"Custom code calling IContentManager.CloneAsync with a hand-built clone content item; a content type where AutoroutePart was removed after items were created; recipe/import flows constructing clones without copying all parts.","solutions":["Ensure the content type definition includes AutoroutePart on both source and clone before cloning.","Use the standard IContentManager clone APIs instead of manually constructing the clone item.","Attach an AutoroutePart to the clone before the Cloning handler runs, copying Path from the source.","Run a migration to re-add AutoroutePart to legacy items missing it."],"exampleFix":"// before\nvar clone = new ContentItem();\nawait _contentManager.CloneAsync(contentItem);\n// after\nvar clone = contentItem.Clone();\nclone.Weld(new AutoroutePart());\nawait _contentManager.CreateAsync(clone);","handlingStrategy":"validation","validationCode":"if (!clone.TryGet<AutoroutePart>(out _)) throw new InvalidOperationException(\"Clone must carry AutoroutePart before cloning.\");","typeGuard":"static bool HasAutoroute(ContentItem item) => item.TryGet<AutoroutePart>(out _);","tryCatchPattern":"try { await _contentManager.CloneAsync(item); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"AutoroutePart\"))\n{\n    logger.LogError(ex, \"Clone of {Id} lacks AutoroutePart\", item.ContentItemId);\n    throw new ValidationException(\"Source type must include AutoroutePart for cloning.\");\n}","preventionTips":["Keep AutoroutePart in the type definition for routable types","Use standard clone APIs, never hand-built clones","Audit imported items for missing parts before cloning","Write migrations when removing parts from a content type"],"tags":["autoroute","cloning","content-items"],"backgroundTag":"missing-dependency","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"}