AvaloniaUI/Avalonia · error · FormatException

Unknown format specifier

Error message

Unknown format specifier

What it means

KeyGesture.ToString(format, provider) supports only the invariant format (null/""/"g", uses Enum.ToString for keys) and the platform format ("p", uses a registered KeyGestureFormatInfo). Any other format string is unknown, so it throws FormatException, mirroring IFormattable conventions.

Source

Thrown at src/Avalonia.Base/Input/KeyGesture.cs:113

        /// <summary>
        /// Returns the current KeyGesture as a string formatted according to the format string and appropriate IFormatProvider
        /// </summary>
        /// <param name="format">The format to use. 
        /// <list type="bullet">
        /// <item><term>null or "" or "g"</term><description>The Invariant format, uses Enum.ToString() to format Keys.</description></item>
        /// <item><term>"p"</term><description>Use platform specific formatting as registerd.</description></item>
        /// </list></param>
        /// <param name="formatProvider">The IFormatProvider to use.  If null, uses the appropriate provider registered in the Avalonia Locator, or Invariant.</param>
        /// <returns>The formatted string.</returns>
        /// <exception cref="FormatException">Thrown if the format string is not null, "", "g", or "p"</exception>
        public string ToString(string? format, IFormatProvider? formatProvider)
        {
            var formatInfo = format switch
            {
                null or "" or "g" => KeyGestureFormatInfo.Invariant,
                "p" => KeyGestureFormatInfo.GetInstance(formatProvider),
                _ => throw new FormatException("Unknown format specifier")
            };

            var s = StringBuilderCache.Acquire();

            static void Plus(StringBuilder s)
            {
                if (s.Length > 0)
                {
                    s.Append("+");
                }
            }

            if (KeyModifiers.HasAllFlags(KeyModifiers.Control))
            {
                s.Append(formatInfo.Ctrl);
            }

            if (KeyModifiers.HasAllFlags(KeyModifiers.Shift))

View on GitHub (pinned to 11c5427268)

Solutions

  1. Use null, "", "g", or "p" as the format specifier.
  2. If you only need the invariant representation, call parameterless ToString().
  3. Register a custom KeyGestureFormatInfo and use "p" for platform-specific output.

Example fix

// before:
var s = gesture.ToString("D", culture); // throws

// after:
var s = gesture.ToString("g", culture); // invariant
// or platform-specific:
var s = gesture.ToString("p", culture);
Defensive patterns

Strategy: validation

Validate before calling

var s = (format is null or "" or "g" or "p")
    ? gesture.ToString(format, provider)
    : throw new FormatException("Unknown format specifier");

Type guard

static bool IsKnownFormat(string? f) => f is null or "" or "g" or "p";

Try / catch

try { return gesture.ToString(fmt, provider); }
catch (FormatException) { return gesture.ToString(); // invariant fallback }

Prevention

When it happens

Trigger: Calling `keyGesture.ToString("x")`, `ToString("D")`, or any specifier other than null/""/"g"/"p".

Common situations: Passing a numeric/standard .NET format string to a KeyGesture. UI code generically forwarding a format string from a formatter setting into ToString.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/830db5a69ebb6799. Report an issue: GitHub.