dotnet/wpf · error · FormatException

SR.InvalidLocalizabilityValue

Error message

SR.InvalidLocalizabilityValue

What it means

ParseLocalizabilityString resolves the [Localization.Attributes] Localizability attribute's category string against the LocalizationCategory enum index table. When the supplied string is not a valid LocalizationCategory name (ignoring the table's aliases), it throws this FormatException.

Solutions

  1. Use an exact LocalizationCategory enum member name (e.g. Text, Button, Title, None, Inherit).
  2. Check spelling and casing against the LocalizationCategory enum in System.Windows.Localization.
  3. Replace invented categories with the closest standard one ('Text' for generic strings, 'NeverLocalize' to exclude).
  4. If a custom grouping is needed, encode it in the Localization.Comments attribute instead of the category.

Example fix

// before
[Localization.Attributes]
Text(TextBlock, Modifiable)
// after
[Localization.Attributes]
Text(Text, Modifiable)
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidLocalizationCategory(string value) =>
    System.Enum.TryParse<System.Windows.LocalizationCategory>(value, out _);

Try / catch

try { ParseLocalizabilityString(value); } catch (FormatException ex) { log.Warn($"Unknown LocalizationCategory '{value}': {ex.Message}"); }

Prevention

When it happens

Trigger: Passing a category string to LocalizabilityAttribute parsing (via LookupAndSetLocalizabilityAttribute) that is not a LocalizationCategory member, e.g. 'TextBlock' or 'Label' instead of valid values like 'Text', 'Title', 'Button', 'None', or 'Inherit'.

Common situations: Typo'd category names in [Localization.Attributes] attributes, using UI element type names as categories, and older project files using category names from a different localization tool's vocabulary.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ede868d5e532c46b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs:266

            if (ReadabilityIndexTable.TryGet(value, out enumValue))
            {
                attributeGroup.Readability = (Readability)enumValue;
                return;
            }

            if (ModifiabilityIndexTable.TryGet(value, out enumValue))
            {
                attributeGroup.Modifiability = (Modifiability)enumValue;
                return;
            }

            if (LocalizationCategoryIndexTable.TryGet(value, out enumValue))
            {
                attributeGroup.Category = (LocalizationCategory)enumValue;
                return;
            }

            throw new FormatException(SR.Format(SR.InvalidLocalizabilityValue, value));
        }


        private const char CommentStart = '(';
        private const char CommentEnd = ')';
        private const char EscapeChar = '\\';

        // loc comments file recognized element
        internal const string LocDocumentRoot = "LocalizableAssembly";
        internal const string LocResourcesElement = "LocalizableFile";
        internal const string LocCommentsElement = "LocalizationDirectives";
        internal const string LocFileNameAttribute = "Name";
        internal const string LocCommentIDAttribute = "Uid";
        internal const string LocCommentsAttribute = "Comments";
        internal const string LocLocalizabilityAttribute = "Attributes";

        //
        // Tables that map the enum string names into their enum indices.

View on GitHub (pinned to 81131a70a4)