{"record":{"id":"731dc898d4bbc507","repo":"dotnet/wpf","slug":"indexoutofrangeexception-themedictionaryextension","errorCode":null,"errorMessage":"IndexOutOfRangeException","messagePattern":"IndexOutOfRangeException","errorType":"exception","errorClass":"IndexOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeDictionaryExtension.cs","lineNumber":136,"sourceCode":"        internal static Uri GenerateFallbackUri(ResourceDictionary dictionary, string resourceName)\n        {\n            Span<Range> splitRegions = stackalloc Range[3];\n            for (int i = 0; i < _themeDictionaryInfos.Count; i++)\n            {\n                ThemeDictionaryInfo info = _themeDictionaryInfos[i];\n\n                if (!info.DictionaryReference.IsAlive)\n                {\n                    // Remove from list\n                    _themeDictionaryInfos.RemoveAt(i);\n                    i--;\n                    continue;\n                }\n                if ((ResourceDictionary)info.DictionaryReference.Target == dictionary)\n                {\n                    ReadOnlySpan<char> nameSpan = resourceName.AsSpan();\n                    if (nameSpan.Split(splitRegions, '/') < 2)\n                        throw new IndexOutOfRangeException();\n\n                    return GenerateUri(info.AssemblyName, resourceName, nameSpan[splitRegions[1]]);\n                }\n            }\n            return null;\n        }\n\n\n        #endregion\n\n        #region Data\n\n        private string _assemblyName;\n\n        #endregion\n\n        #region Static Data\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeDictionaryExtension.cs#L118-L154","documentation":"GenerateFallbackUri walks previously registered theme dictionaries to build a fallback URI from their resource name. It expects the stored resource name to contain at least two '/'-delimited segments (it splits and indexes segment [1]). When fewer segments exist, the bare IndexOutOfRangeException is thrown — effectively an internal invariant violation.","triggerScenarios":"A dictionary registered via Register() whose resourceName lacks a second path segment (e.g. 'themes.xaml' instead of 'themes/light.xaml') when a fallback URI is generated after a theme change.","commonSituations":"Custom or legacy theme dictionary registrations with flat resource names; mismatch between a hand-built dictionary source path and what UxThemeWrapper expects during fallback theme resolution.","solutions":["Ensure the Source URIs of theme dictionaries contain at least two path segments (e.g. 'pack://application:,,,/Assembly;component/Themes/ThemeName.xaml').","Locate the offending registered dictionary and correct its Source path.","Catch this during theme-switch code paths and fall back to a fully qualified pack URI."],"exampleFix":"// before\ndictionary.Source = new Uri(\"pack://application:,,,/App;component/flat.xaml\");\n// after\ndictionary.Source = new Uri(\"pack://application:,,,/App;component/Themes/Custom.xaml\");","handlingStrategy":"try-catch","validationCode":"var segments = dictionary.Source?.AbsolutePath?.Split('/');\nif (segments == null || segments.Length < 2)\n    throw new InvalidOperationException(\"Theme dictionary source needs >= 2 path segments for fallback resolution.\");","typeGuard":null,"tryCatchPattern":"try { var uri = GenerateFallbackUri(dictionary, resourceName); }\ncatch (IndexOutOfRangeException) { return GenerateUri(assemblyName, resourceName, defaultTheme); }","preventionTips":["Use hierarchical theme paths like Themes/<ThemeName>.xaml.","Avoid flat filenames for theme dictionaries.","Test theme-switch/fallback code paths with all registered dictionaries."],"tags":["wpf","theme","index-out-of-range"],"backgroundTag":"index-out-of-bounds","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"}