OrchardCMS/OrchardCore · error · InvalidOperationException
There is already another index with the same name.
Error message
There is already another index with the same name.
What it means
DefaultIndexProfileStore.UpdateAsync enforces uniqueness of index profiles before saving. It throws InvalidOperationException if another profile with the same IndexName + ProviderName already exists (different Id), and also checks for a duplicate Name. This prevents two index profiles competing for the same index in the search/indexing system.
Solutions
- Before updating, query the store for an existing profile with the same IndexName/ProviderName and update that record instead of creating a new one.
- Use a unique IndexName (e.g. suffix with tenant/scope) for the new profile.
- In recipes/migrations, guard the creation step with an existence check or make the step idempotent.
- Catch InvalidOperationException around UpdateAsync and surface a duplicate-name validation error in the admin UI.
Example fix
// before
await indexProfileStore.UpdateAsync(new IndexProfile { IndexName = "ArticlesIndex", ProviderName = "Lucene", ... });
// after
var existing = (await indexProfileStore.ListAsync())
.FirstOrDefault(p => p.IndexName == "ArticlesIndex" && p.ProviderName == "Lucene");
if (existing is null)
{
await indexProfileStore.UpdateAsync(new IndexProfile { IndexName = "ArticlesIndex", ProviderName = "Lucene", ... });
}
else
{
existing.Source = ...; // mutate the existing profile instead
await indexProfileStore.UpdateAsync(existing);
} Defensive patterns
Strategy: try-catch
Validate before calling
var duplicate = (await indexProfileStore.ListAsync())
.Any(p => p.IndexName == profile.IndexName && p.ProviderName == profile.ProviderName && p.Id != profile.Id);
if (duplicate)
{
throw new InvalidOperationException($"An index profile named '{profile.IndexName}' ({profile.ProviderName}) already exists.");
} Try / catch
try
{
await indexProfileStore.UpdateAsync(profile);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("another index with the same name"))
{
modelState.AddModelError(nameof(profile.IndexName), "An index with this name already exists.");
} Prevention
- Make recipe/migration index-creation steps idempotent by checking existence first.
- Derive IndexName from a tenant/scope-prefixed convention to avoid collisions across sites.
- Handle duplicate-name validation in admin editors before calling UpdateAsync.
- Never rename an index profile's IndexName to a name already used by another profile with the same provider.
When it happens
Trigger: Calling IIndexProfileStore.UpdateAsync with an index profile whose (IndexName, ProviderName) pair matches an existing profile with a different Id - e.g. importing a recipe or JSON step that re-declares an existing index, or renaming a profile's Name/IndexName to collide.
Common situations: Recipe re-runs or migrations that create index profiles without an existence check; two admins creating the same index name concurrently; copy-pasting an index profile definition and only changing the display name; importing settings from another site.
Related errors
- The index does not have a key field.
- An ambiguous index has been found.
- Index mappings cannot be null.
- Both the index-name and index full-name must be set.
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/6e669de809c4d465.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Indexing.Core/DefaultIndexProfileStore.cs:119
public ValueTask CreateAsync(IndexProfile indexProfile)
=> UpdateAsync(indexProfile);
public async ValueTask UpdateAsync(IndexProfile indexProfile)
{
ArgumentNullException.ThrowIfNull(indexProfile);
if (string.IsNullOrEmpty(indexProfile.Id))
{
indexProfile.Id = IdGenerator.GenerateId();
}
var exists = await _session.QueryIndex<IndexProfileIndex>()
.Where(x => x.IndexName == indexProfile.IndexName && x.ProviderName == indexProfile.ProviderName && x.IndexProfileId != indexProfile.Id)
.FirstOrDefaultAsync();
if (exists is not null)
{
throw new InvalidOperationException("There is already another index with the same name.");
}
var existsByName = await _session.QueryIndex<IndexProfileIndex>()
.Where(x => x.Name == indexProfile.Name && x.IndexProfileId != indexProfile.Id)
.FirstOrDefaultAsync();
if (existsByName is not null)
{
throw new InvalidOperationException("There is already another index with the same name.");
}
await _session.SaveAsync(indexProfile, checkConcurrency: true);
}
private IQuery<IndexProfile, IndexProfileIndex> BuildQuery(QueryContext context)
{
var query = _session.Query<IndexProfile, IndexProfileIndex>();
View on GitHub (pinned to 4306c0717f)