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

  1. Before updating, query the store for an existing profile with the same IndexName/ProviderName and update that record instead of creating a new one.
  2. Use a unique IndexName (e.g. suffix with tenant/scope) for the new profile.
  3. In recipes/migrations, guard the creation step with an existence check or make the step idempotent.
  4. 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

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


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)