{"record":{"id":"a72e4e685f09401e","repo":"dotnet/wpf","slug":"sr-filedialoginvalidfilterindex","errorCode":null,"errorMessage":"SR.FileDialogInvalidFilterIndex","messagePattern":"SR\\.FileDialogInvalidFilterIndex","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/FileDialog.cs","lineNumber":712,"sourceCode":"                // Calculate the index of the token containing extension(s) selected\n                // by the FilterIndex property.  Remember FilterIndex is one based.\n                // Multiply by 2 because each filter consists of 2 strings.\n                // Now subtract one to get to the filter component.\n                //\n                // example:  Text|*.txt|Pictures|*.jpg|Web Pages|*.htm\n                // tokens[]:   0    1       2      3      4        5\n                // FilterIndex = 2 selects Pictures;  (2*2)-1 = 3 points to *.jpg in tokens\n                //\n                int indexOfExtension = (_filterIndex * 2) - 1;\n\n                // Check to be sure our filter index is not out of bounds (that is,\n                // greater than the number of filters we actually have).\n                // We multiply by 2 here because each filter consists of two strings,\n                // description and extensions, both separated by | characters.. so\n                // tokens.length is actually twice the number of filters we have.\n                if (indexOfExtension >= tokens.Length)\n                {\n                    throw new InvalidOperationException(SR.FileDialogInvalidFilterIndex);\n                }\n\n                // If our filter index is valid (0 is reserved by Windows for custom\n                // filter functionality we don't expose, so filters must be 1 or greater)\n                if (_filterIndex > 0)\n                {\n                    // Find our filter in the tokens list, then split it on the\n                    // ';' character (which is the filter extension delimiter)\n                    ReadOnlySpan<char> exts = tokens[indexOfExtension].AsSpan();\n\n                    foreach (Range ext in exts.Split(';'))\n                    {\n                        // Filter extensions should be in the form *.txt or .txt,\n                        // so we strip out everything before and including the '.'\n                        // before adding the extension to our list.\n                        // If the extension has no '.', we just ignore it as invalid.\n                        int i = exts[ext].LastIndexOf('.');\n","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/FileDialog.cs#L694-L730","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\ndlg.Filter = \"Text|*.txt\";\ndlg.FilterIndex = 2; // only 1 filter\n// after\ndlg.Filter = \"Text|*.txt\";\ndlg.FilterIndex = 1;","handlingStrategy":"validation","validationCode":"int filterCount = dlg.Filter.Split('|').Length / 2;\nif (dlg.FilterIndex < 1 || dlg.FilterIndex > filterCount)\n    dlg.FilterIndex = 1;","typeGuard":null,"tryCatchPattern":"try { var files = dlg.FileNames; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"filter\"))\n{\n    dlg.FilterIndex = 1; // reset and retry\n}","preventionTips":["Remember FilterIndex is 1-based","Reset FilterIndex whenever you change Filter","Validate any config-driven filter index against the actual filter count"],"tags":["wpf","filedialog","filter-index","state"],"backgroundTag":"value-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}