dotnet/wpf · error · ArgumentException

SR.FileDialogInvalidFilter

Error message

SR.FileDialogInvalidFilter

What it means

FileDialog.Filter validates the filter string by counting '|' separators; an even number of pipes means the string does not resolve to description/extension pairs (each pair needs an odd, properly matched set of separators). An ArgumentException is thrown because the filter cannot be parsed into Win32 filter pairs.

Solutions

  1. Use the format "Description|*.ext1;*.ext2|Description2|*.ext3" with an odd number of '|' separators forming complete pairs
  2. Remove trailing or doubled '|' characters from the filter string
  3. Ensure every description is followed by at least one extension pattern
  4. Build filters programmatically with string.Join("|", pairs) instead of manual concatenation

Example fix

// before
dlg.Filter = "Text files|*.txt|"; // trailing pipe -> even count
// after
dlg.Filter = "Text files|*.txt"; // or "Text|*.txt|All|*.*"
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidFilter(string f) =>
    !string.IsNullOrWhiteSpace(f) && f.Split('|').Length % 2 == 1 && !f.EndsWith("|");

Try / catch

try { dlg.Filter = filter; }
catch (ArgumentException ex) when (ex.Message.Contains("filter") || ex.ParamName == "value")
{
    dlg.Filter = "All files (*.*)|*.*";
}

Prevention

When it happens

Trigger: Setting OpenFileDialog.Filter (or SaveFileDialog.Filter) to a malformed string, e.g. "Text files|*.txt|" (trailing pipe) or "*.txt" (no description) or "A|*.a|B" (unbalanced pairs).

Common situations: Hand-editing a filter string and leaving a stray trailing '|'; building the filter dynamically by concatenation and appending a separator after the last entry; loading filter definitions from config with whitespace/format errors.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/FileDialog.cs:327

            {
                if (!string.Equals(value, _filter, StringComparison.Ordinal))   // different filter than what we have stored already
                {
                    string updatedFilter = value;

                    if (!string.IsNullOrEmpty(updatedFilter))
                    {
                        // Require the number of segments of the filter string to be even -
                        // in other words, there must only be matched pairs of description and
                        // file extensions.
                        //
                        // This implicitly requires there to be at least one vertical bar in
                        // the filter string - or else formatsCount will be 1, resulting in an
                        // ArgumentException.
                        int formatsCount = updatedFilter.AsSpan().Count('|');

                        if (formatsCount % 2 == 0)
                        {
                            throw new ArgumentException(SR.FileDialogInvalidFilter);
                        }
                    }
                    else
                    {   // catch cases like null or "" where the filter string is not invalid but
                        // also not substantive.  We set value to null so that the assignment
                        // below picks up null as the new value of _filter.
                        updatedFilter = null;
                    }

                    _filter = updatedFilter;
                }
            }
        }

        //   Using 1 as the index of the first filter entry is counterintuitive for C#/C++
        //   developers, but is a side effect of a Win32 feature that allows you to add a template
        //   filter string that is filled in when the user selects a file for future uses of the dialog.
        //   We don't support that feature, so only values >1 are valid.

View on GitHub (pinned to 81131a70a4)