dotnet/wpf · error · InvalidOperationException
SR.FileDialogInvalidFilterIndex
Error message
SR.FileDialogInvalidFilterIndex
What it means
GetFilterExtensions reads the dialog's FilterIndex to pick which filter's extensions to report; if the index is at or beyond the number of parsed filter tokens (i.e. the filter index points at a nonexistent filter), an InvalidOperationException is thrown. FilterIndex is 1-based, with 0 reserved by Windows for the custom-entry slot.
Solutions
- Ensure FilterIndex is between 1 and the number of filter pairs in Filter before showing the dialog
- Reset FilterIndex to 1 after changing the Filter string
- Validate: if (dlg.FilterIndex < 1 || dlg.FilterIndex > countOfFilters) dlg.FilterIndex = 1;
- Never assign 0 to FilterIndex (reserved by Windows for custom filters)
Example fix
// before dlg.Filter = "Text|*.txt"; dlg.FilterIndex = 2; // only 1 filter // after dlg.Filter = "Text|*.txt"; dlg.FilterIndex = 1;
Defensive patterns
Strategy: validation
Validate before calling
int filterCount = dlg.Filter.Split('|').Length / 2;
if (dlg.FilterIndex < 1 || dlg.FilterIndex > filterCount)
dlg.FilterIndex = 1; Try / catch
try { var files = dlg.FileNames; }
catch (InvalidOperationException ex) when (ex.Message.Contains("filter"))
{
dlg.FilterIndex = 1; // reset and retry
} Prevention
- Remember FilterIndex is 1-based
- Reset FilterIndex whenever you change Filter
- Validate any config-driven filter index against the actual filter count
When it happens
Trigger: Setting FileDialog.FilterIndex to a value larger than the number of filters in the Filter string before calling ShowDialog or reading FileNames/Extensions; a stale FilterIndex left from a previous dialog configuration whose Filter string was then shortened.
Common situations: Hardcoding FilterIndex = 2 while the Filter has only one entry; programmatically changing Filter after a dialog was used, leaving the old index; off-by-one confusion between 0-based and 1-based indexing.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- E_FAIL
- FILTER_E_ACCESS
- InvalidOperationException
- InvalidOperationException (no message)
- SR.CannotChangePublishLicense
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a72e4e685f09401e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/FileDialog.cs:712
// Calculate the index of the token containing extension(s) selected
// by the FilterIndex property. Remember FilterIndex is one based.
// Multiply by 2 because each filter consists of 2 strings.
// Now subtract one to get to the filter component.
//
// example: Text|*.txt|Pictures|*.jpg|Web Pages|*.htm
// tokens[]: 0 1 2 3 4 5
// FilterIndex = 2 selects Pictures; (2*2)-1 = 3 points to *.jpg in tokens
//
int indexOfExtension = (_filterIndex * 2) - 1;
// Check to be sure our filter index is not out of bounds (that is,
// greater than the number of filters we actually have).
// We multiply by 2 here because each filter consists of two strings,
// description and extensions, both separated by | characters.. so
// tokens.length is actually twice the number of filters we have.
if (indexOfExtension >= tokens.Length)
{
throw new InvalidOperationException(SR.FileDialogInvalidFilterIndex);
}
// If our filter index is valid (0 is reserved by Windows for custom
// filter functionality we don't expose, so filters must be 1 or greater)
if (_filterIndex > 0)
{
// Find our filter in the tokens list, then split it on the
// ';' character (which is the filter extension delimiter)
ReadOnlySpan<char> exts = tokens[indexOfExtension].AsSpan();
foreach (Range ext in exts.Split(';'))
{
// Filter extensions should be in the form *.txt or .txt,
// so we strip out everything before and including the '.'
// before adding the extension to our list.
// If the extension has no '.', we just ignore it as invalid.
int i = exts[ext].LastIndexOf('.');
View on GitHub (pinned to 81131a70a4)