OrchardCMS/OrchardCore · error · InvalidOperationException

The index does not have a key field.

Error message

The index {index.IndexFullName} does not have a key field.

What it means

Azure AI Search requires every index to declare exactly one key field. This throw fires when the index's AzureAISearchIndexMetadata mappings contain no field marked IsKey, so a key field name cannot be resolved to build or delete documents.

Solutions

  1. Open the index profile in the admin UI and set one field as the key field
  2. Re-create the index ensuring the key field (e.g., ContentItemId) is marked IsKey in the mappings
  3. Fix the AzureAISearchIndexMetadata IndexMappings in storage to include a mapping with IsKey=true

Example fix

// before
mappings: [ { AzureFieldKey: "Title", IsKey: false } ]
// after
mappings: [ { AzureFieldKey: "ContentItemId", IsKey: true } ]
Defensive patterns

Strategy: validation

Validate before calling

var hasKey = index.GetOrCreate<AzureAISearchIndexMetadata>().IndexMappings.Any(m => m.IsKey && !string.IsNullOrEmpty(m.AzureFieldKey));

Type guard

bool hasKeyField = metadata?.IndexMappings?.FirstOrDefault(m => m.IsKey)?.AzureFieldKey is { Length: > 0 };

Try / catch

try { keyName = GetKeyFieldNameOrThrow(index); } catch (InvalidOperationException ex) when (ex.Message.Contains("does not have a key field")) { /* recreate index with key mapping */ }

Prevention

When it happens

Trigger: Calling GetKeyFieldNameOrThrow (via keyName resolution during document indexing/deletion) for an index profile whose IndexMappings lack any mapping with IsKey=true.

Common situations: Index created through a recipe or migration that omitted the key field mapping; mappings edited manually and the key flag removed; corrupted or partially migrated index metadata.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/8d078197f145cff8. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.AzureAI.Core/Services/AzureAISearchDocumentIndexManager.cs:243

        index.Alter<ContentIndexingMetadata>(metadata =>
        {
            metadata.LastTaskId = lastTaskId;
        });

        await _indexStore.UpdateAsync(index);
    }

    public IContentIndexSettings GetContentIndexSettings()
        => new AzureAISearchContentIndexSettings();

    private static string GetKeyFieldNameOrThrow(IndexProfile index)
    {
        var keyName = index.GetOrCreate<AzureAISearchIndexMetadata>().IndexMappings.FirstOrDefault(x => x.IsKey)?.AzureFieldKey;

        if (string.IsNullOrEmpty(keyName))
        {
            throw new InvalidOperationException($"The index {index.IndexFullName} does not have a key field.");
        }

        return keyName;
    }

    private IEnumerable<SearchDocument> CreateSearchDocuments(IEnumerable<DocumentIndex> indexDocuments, Dictionary<string, IEnumerable<AzureAISearchIndexMap>> mappings)
    {
        foreach (var indexDocument in indexDocuments)
        {
            yield return CreateSearchDocument(indexDocument, mappings);
        }
    }

    private SearchDocument CreateSearchDocument(DocumentIndex documentIndex, Dictionary<string, IEnumerable<AzureAISearchIndexMap>> mappingDictionary)
    {
        var doc = new SearchDocument();

        if (documentIndex is ContentItemDocumentIndex index)

View on GitHub (pinned to 4306c0717f)