{"record":{"id":"0a5c0c834dea057f","repo":"OrchardCMS/OrchardCore","slug":"unable-to-create-a-unique-index-name-for-indexname-after-50","errorCode":null,"errorMessage":"Unable to create a unique index name for '{indexName}' after 50 attempts.","messagePattern":"Unable to create a unique index name for '(.+?)' after 50 attempts\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.AzureAI/Migrations/AzureAISearchIndexSettingsMigrations.cs","lineNumber":143,"sourceCode":"                indexProfile.IndexFullName = indexNameProvider.GetFullIndexName(indexName);\n                indexProfile.Name = indexName;\n\n                var counter = 1;\n\n                var properties = indexObject.Value[nameof(indexProfile.Properties)]?.AsObject();\n\n                if (properties is not null && properties.Count > 0)\n                {\n                    indexProfile.Properties = properties.Clone();\n                }\n\n                while (await indexProfileManager.FindByNameAsync(indexProfile.Name) is not null)\n                {\n                    indexProfile.Name = $\"{indexName}{counter++}\";\n\n                    if (counter > 50)\n                    {\n                        throw new InvalidOperationException($\"Unable to create a unique index name for '{indexName}' after 50 attempts.\");\n                    }\n                }\n\n                var id = indexObject.Value[\"Id\"]?.GetValue<string>();\n\n                if (!string.IsNullOrEmpty(id))\n                {\n                    indexProfile.Id = id;\n                }\n\n                var metadata = indexProfile.GetOrCreate<ContentIndexMetadata>();\n\n                if (string.IsNullOrEmpty(metadata.Culture))\n                {\n                    metadata.Culture = indexObject.Value[nameof(metadata.Culture)]?.GetValue<string>();\n                }\n\n                var indexLatest = indexObject.Value[nameof(metadata.IndexLatest)]?.GetValue<bool>();","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.AzureAI/Migrations/AzureAISearchIndexSettingsMigrations.cs#L125-L161","documentation":"During AzureAISearchIndexSettingsMigrations.UpdateFrom1, legacy index names are migrated to index profiles; when the generated name collides with an existing profile the code appends an incrementing counter. If no unique name is found after 50 attempts it throws InvalidOperationException to abort the migration safely rather than overwrite an existing profile.","triggerScenarios":"Running the AzureAI migration on a system that already contains many index profiles named '<indexName>0'...'<indexName>50'; duplicate legacy index names across tenants; repeated migration runs creating sequential collisions.","commonSituations":"Upgrading an Orchard Core site where Azure AI Search index profiles were manually created with names matching legacy search indexes; sites with a large number of similarly-named indexes.","solutions":["Rename or delete conflicting index profiles so the migrated name is free, then re-run the migration.","Roll back the migration, consolidate duplicate indexes, and update again.","Inspect the index profiles table for names like '<indexName>N' to identify the collisions.","Back up the database before retrying the migration."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Detect collisions before migrating:\nvar conflicts = profiles.Where(p => Regex.IsMatch(p.Name, $\"^{Regex.Escape(baseName)}\\\\d*$\"));\nif (conflicts.Count() > 1) logger.LogWarning(\"Index name collisions likely for {Base}\", baseName);","typeGuard":null,"tryCatchPattern":"try { await migration.UpdateFrom1Async(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"unique index name\"))\n{\n    logger.LogError(ex, \"AzureAI index migration blocked by name collisions; rename conflicting profiles manually\");\n}","preventionTips":["Back up the database before running migrations","Review existing index profile names before upgrading","Avoid manually creating profiles named like legacy search indexes","Test the upgrade on a staging copy first"],"tags":["azure-ai-search","migration","naming-collision"],"backgroundTag":"internal-invariant-violation","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}