{"record":{"id":"4ab28683af20afef","repo":"OrchardCMS/OrchardCore","slug":"cannot-localize-an-unsupported-culture","errorCode":null,"errorMessage":"Cannot localize an unsupported culture","messagePattern":"Cannot localize an unsupported culture","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.ContentLocalization/DefaultContentLocalizationManager.cs","lineNumber":71,"sourceCode":"    }\n\n    public async Task<IEnumerable<ContentItem>> GetItemsForSetAsync(string localizationSet)\n    {\n        return await _session.Query<ContentItem, LocalizedContentItemIndex>(i => (i.Published || i.Latest) && i.LocalizationSet == localizationSet).ListAsync();\n    }\n\n    public async Task<IEnumerable<ContentItem>> GetItemsForSetsAsync(IEnumerable<string> localizationSets, string culture)\n    {\n        var invariantCulture = culture.ToLowerInvariant();\n        return await _session.Query<ContentItem, LocalizedContentItemIndex>(i => (i.Published || i.Latest) && i.LocalizationSet.IsIn(localizationSets) && i.Culture == invariantCulture).ListAsync();\n    }\n\n    public async Task<ContentItem> LocalizeAsync(ContentItem content, string targetCulture)\n    {\n        var supportedCultures = await _localizationService.GetSupportedCulturesAsync();\n        if (!supportedCultures.Any(c => string.Equals(c, targetCulture, StringComparison.OrdinalIgnoreCase)))\n        {\n            throw new InvalidOperationException(\"Cannot localize an unsupported culture\");\n        }\n\n        var localizationPart = content.GetOrCreate<LocalizationPart>();\n        if (string.IsNullOrEmpty(localizationPart.LocalizationSet))\n        {\n            // If the source content item is not yet localized, define its defaults.\n            localizationPart.LocalizationSet = _iidGenerator.GenerateUniqueId();\n            localizationPart.Culture = await _localizationService.GetDefaultCultureAsync();\n            await _session.SaveAsync(content);\n        }\n        else\n        {\n            var existingContent = await GetContentItemAsync(localizationPart.LocalizationSet, targetCulture);\n\n            if (existingContent != null)\n            {\n                // Already localized.\n                return existingContent;","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.ContentLocalization/DefaultContentLocalizationManager.cs#L53-L89","documentation":"DefaultContentLocalizationManager.LocalizeAsync validates the requested target culture against the site's configured supported cultures (ILocalizationService.GetSupportedCulturesAsync) using a case-insensitive comparison. If the culture is not supported it throws InvalidOperationException, because localization cannot proceed without a culture the site can serve.","triggerScenarios":"Calling IContentLocalizationManager.LocalizeAsync(content, targetCulture) with a culture string that is not enabled under Settings > Localization (e.g. 'fr-FR' when only 'en-US' and 'de' are configured), or with a misspelled culture code.","commonSituations":"Programmatic translation workflows passing cultures that were never added to the site; cultures removed from settings after custom code was written; regional variants ('pt-BR' vs 'pt') not configured.","solutions":["Add the target culture in admin Settings > Localization before localizing.","Pass a culture exactly as listed by ILocalizationService.GetSupportedCulturesAsync (case-insensitive).","Validate the culture with the supported-cultures list in your own code before calling LocalizeAsync.","Fall back to a supported parent culture (e.g. 'fr' instead of 'fr-CA') if the regional variant is absent."],"exampleFix":"// before\nawait _contentLocalizationManager.LocalizeAsync(item, \"fr-CA\"); // throws if not supported\n// after\nvar supported = await _localizationService.GetSupportedCulturesAsync();\nvar culture = supported.FirstOrDefault(c => c.StartsWith(\"fr\", StringComparison.OrdinalIgnoreCase)) ?? throw new InvalidOperationException(\"Add a French culture first\");\nawait _contentLocalizationManager.LocalizeAsync(item, culture);","handlingStrategy":"validation","validationCode":"var supported = await _localizationService.GetSupportedCulturesAsync();\nif (!supported.Any(c => string.Equals(c, targetCulture, StringComparison.OrdinalIgnoreCase)))\n    throw new ArgumentException($\"Culture '{targetCulture}' is not enabled for this site.\", nameof(targetCulture));","typeGuard":"static bool IsSupportedCulture(IEnumerable<string> supported, string culture) => supported.Any(c => string.Equals(c, culture, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { var localized = await _contentLocalizationManager.LocalizeAsync(item, culture); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Cannot localize an unsupported culture\")\n{\n    logger.LogWarning(\"Culture {Culture} not enabled; falling back to source item\", culture);\n    localized = item;\n}","preventionTips":["Add all needed cultures in Settings > Localization before automating translation","Fetch the supported list at runtime instead of hard-coding culture strings","Validate culture codes with CultureInfo.GetCultureInfo before calling","Fall back to the parent culture when a regional variant is missing"],"tags":["contentlocalization","culture","validation"],"backgroundTag":"unsupported-operation","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"}