OrchardCMS/OrchardCore · critical · InvalidOperationException
The content item is missing a 'ContentItemId'.
Error message
The content item is missing a 'ContentItemId'.
What it means
DefaultContentManager.CreateContentItemVersionAsync throws InvalidOperationException when the ContentItem has no ContentItemId. Versioned creation is only for items that already have an identity (loaded or built via NewAsync); a new item must be created through NewAsync so the manager can assign the ID.
Solutions
- Create the item via await _contentManager.NewAsync("TypeName", VersionOptions.Draft) so ContentItemId is assigned.
- If versioning an existing item, load it with _contentManager.GetAsync(contentItemId, VersionOptions.*) instead of constructing a new instance.
- Check your deserialization/import code preserves the ContentItemId property.
- Wrap the call in try/catch InvalidOperationException and fall back to NewAsync for genuinely new items.
Example fix
// before
var item = new ContentItem { ContentType = "Article" };
await _contentManager.CreateContentItemVersionAsync(item);
// after
var item = await _contentManager.NewAsync("Article", VersionOptions.Draft);
await _contentManager.CreateContentItemVersionAsync(item); Defensive patterns
Strategy: try-catch
Validate before calling
if (string.IsNullOrEmpty(contentItem.ContentItemId))
{
// must create via NewAsync before versioning
} Type guard
bool CanCreateVersion(ContentItem item) => item is not null && !string.IsNullOrEmpty(item.ContentItemId);
Try / catch
try
{
await _contentManager.CreateContentItemVersionAsync(item);
}
catch (InvalidOperationException)
{
// fall back: create via NewAsync for genuinely new items
var fresh = await _contentManager.NewAsync(item.ContentType, VersionOptions.Draft);
// copy fields/parts then create
} Prevention
- Always obtain new content items from IContentManager.NewAsync, never 'new ContentItem()'.
- Preserve ContentItemId in import/serialization code.
- Add a guard helper that asserts ContentItemId before calling version APIs.
When it happens
Trigger: Calling IContentManager.CreateContentItemVersionAsync with a ContentItem constructed with 'new ContentItem()' instead of IContentManager.NewAsync, or deserializing/hand-building an item and dropping its ContentItemId, or passing a default-constructed item to SaveContentItemAsync paths that route into version creation.
Common situations: Import/migration scripts that build ContentItem objects manually, unit tests constructing content items by hand, custom modules cloning items but clearing ContentItemId, serialization round-trips that omit the id property.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Workflow with ID does not have a start activity.
- Unknown XmlRpc value type
- Unknown token type
- Deserializing a is not supported.
- Cannot perform this operation because the shell scope for…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/6abf00740afd910f.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs:1002
var context = new CloneContentContext(contentItem, cloneContentItem);
context.CloneContentItem.Data = contentItem.Data.Clone();
await Handlers.InvokeAsync((handler, context) => handler.CloningAsync(context), context, _logger);
await _session.SaveAsync(context.CloneContentItem);
await ReversedHandlers.InvokeAsync((handler, context) => handler.ClonedAsync(context), context, _logger);
return context.CloneContentItem;
}
private async Task<ContentValidateResult> CreateContentItemVersionAsync(ContentItem contentItem, IEnumerable<ContentItem> evictionVersions = null)
{
if (string.IsNullOrEmpty(contentItem.ContentItemId))
{
// NewAsync should be used to create new content items.
throw new InvalidOperationException($"The content item is missing a '{nameof(ContentItem.ContentItemId)}'.");
}
// Initializes the Id as it could be interpreted as an updated object when added back to YesSql
contentItem.Id = 0;
// Maintain modified and published dates as these will be reset by the Create Handlers
var modifiedUtc = contentItem.ModifiedUtc;
var publishedUtc = contentItem.PublishedUtc;
var owner = contentItem.Owner;
var author = contentItem.Author;
if (string.IsNullOrEmpty(contentItem.ContentItemVersionId))
{
contentItem.ContentItemVersionId = _idGenerator.GenerateUniqueId(contentItem);
}
// Remove previous latest item or they will continue to be listed as latest.
// When importing a new draft the existing latest must be set to false. The creating version wins.View on GitHub (pinned to 4306c0717f)