dotnet/wpf · error · InvalidOperationException
SR.Format(SR.XmlLangGetSpecificCulture, _lowerCaseTag)
Error message
SR.Format(SR.XmlLangGetSpecificCulture, _lowerCaseTag)
What it means
XmlLanguage.GetSpecificCulture derives a specific (region-qualified) culture from the equivalent culture; when the compatible culture's IetfLanguageTag is empty (i.e. it corresponds to the invariant culture) there is no specific culture to create, so it throws InvalidOperationException naming the original tag.
Solutions
- Guard against XmlLanguage.Empty / empty IetfLanguageTag before calling GetSpecificCulture and use CultureInfo.InvariantCulture directly instead
- Ensure the document or property carries a real xml:lang value (e.g. "en-US") rather than an empty string
- Catch InvalidOperationException and fall back to CurrentCulture for formatting/sorting
- Use GetEquivalentCulture/TryGetEquivalentCulture when only language (not region) matters
Example fix
// before
CultureInfo specific = xmlLang.GetSpecificCulture(); // throws for empty tag
// after
CultureInfo specific = xmlLang.IetfLanguageTag.Length == 0
? CultureInfo.InvariantCulture
: xmlLang.GetSpecificCulture(); Defensive patterns
Strategy: type-guard
Validate before calling
bool canGetSpecific = xmlLang != null && xmlLang.IetfLanguageTag.Length > 0;
Type guard
static bool HasSpecificCulture(XmlLanguage lang) => lang != null && lang != XmlLanguage.Empty && lang.IetfLanguageTag.Length > 0;
Try / catch
try { ci = xmlLang.GetSpecificCulture(); }
catch (InvalidOperationException) { ci = CultureInfo.CurrentCulture; } Prevention
- Check for XmlLanguage.Empty before requesting a specific culture
- Ensure xml:lang is populated in documents
- Use InvariantCulture explicitly when no language is set
When it happens
Trigger: Calling GetSpecificCulture on an XmlLanguage built from an empty or unrecognized tag whose GetCompatibleCulture resolves to the invariant culture (empty IetfLanguageTag).
Common situations: Binding code that calls GetSpecificCulture for sorting/formatting on documents with empty or invalid xml:lang; passing CultureInfo.InvariantCulture-derived languages through localization pipelines; default XmlLanguage.Empty being used in GetCultureInfo paths.
Related errors
- SR.Format(SR.XmlLangGetCultureFailure, lowerCaseTag)
- SR.SpecificNumberCultureRequired
- SR.CannotConvertStringToType
- SR.Format(SR.RequiresExplicitCulture, TargetProperty.Name)
- " }} " element found. Expected fixed page element ( }} ).
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3f7e9b67f78bb9a3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Markup/XmlLanguage.cs:236
/// Finds the registered CultureInfo matching the longest-possible prefix of this XmlLanguage.
/// If that registered CultureInfo is Neutral, then relies on
/// CultureInfo.CreateSpecificCulture() to map from a Neutral CultureInfo to a Specific one.
/// </remarks>
public CultureInfo GetSpecificCulture()
{
if (_specificCulture == null)
{
if (_lowerCaseTag.Length == 0 || string.Equals(_lowerCaseTag, "und", StringComparison.Ordinal))
{
_specificCulture = GetEquivalentCulture();
}
else
{
CultureInfo culture = GetCompatibleCulture();
if (culture.IetfLanguageTag.Length == 0)
{
throw new InvalidOperationException(SR.Format(SR.XmlLangGetSpecificCulture, _lowerCaseTag));
}
if (!culture.IsNeutralCulture)
{
_specificCulture = culture;
}
else
{
try
{
// note that it's important that we use culture.Name, not culture.IetfLanguageTag, here
culture = CultureInfo.CreateSpecificCulture(culture.Name);
_specificCulture = CultureInfo.GetCultureInfoByIetfLanguageTag(culture.IetfLanguageTag);
}
catch (ArgumentException e)
{
throw new InvalidOperationException(SR.Format(SR.XmlLangGetSpecificCulture, _lowerCaseTag), e);
}View on GitHub (pinned to 81131a70a4)