{"record":{"id":"92326115d59ad0cf","repo":"dotnet/wpf","slug":"sr-format-sr-customdictionaryfailedtoloaddictionaryuri-923261","errorCode":null,"errorMessage":"SR.Format(SR.CustomDictionaryFailedToLoadDictionaryUri, lexiconFilePath)","messagePattern":"SR\\.Format\\(SR\\.CustomDictionaryFailedToLoadDictionaryUri, lexiconFilePath\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/WinRTSpellerInterop.cs","lineNumber":430,"sourceCode":"        ///\n        ///     If no culture is specified in the first line of <paramref name=\"lexiconFilePath\"/>\n        ///     in the format #LID nnnn (where nnnn = decimal LCID of the culture), then invariant\n        ///     culture is returned.\n        /// </returns>\n        /// <remarks>\n        ///     At the end of this method, we guarantee that <paramref name=\"lexiconFilePath\"/>\n        ///     can be reclaimed (i.e., potentially deleted) by the caller.\n        /// </remarks>\n        private Tuple<string, string> LoadDictionaryImpl(string lexiconFilePath)\n        {\n            if (_isDisposed)\n            {\n                return new Tuple<string, string>(null, null);\n            }\n\n            if (!File.Exists(lexiconFilePath))\n            {\n                throw new ArgumentException(SR.Format(SR.CustomDictionaryFailedToLoadDictionaryUri, lexiconFilePath));\n            }\n\n            bool fileCopied = false;\n            string lexiconPrivateCopyPath = null;\n\n            try\n            {\n                CultureInfo culture = null;\n\n                // Read the first line of the file and detect culture, if specified\n                using (FileStream stream = new FileStream(lexiconFilePath, FileMode.Open, FileAccess.Read))\n                {\n                    string line = null;\n                    using (StreamReader reader = new StreamReader(stream))\n                    {\n                        line = reader.ReadLine();\n                        culture = WinRTSpellerInterop.TryParseLexiconCulture(line);\n                    }","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/WinRTSpellerInterop.cs#L412-L448","documentation":"WinRTSpellerInterop.LoadDictionaryImpl throws ArgumentException when the custom dictionary (lexicon) file does not exist at the supplied path. WPF spell-checking custom dictionaries must be a real file on disk before being registered, so the API fails fast with a message naming the missing path.","triggerScenarios":"Calling SpellingReform/CustomDictionaries.Add (via LoadDictionary -> LoadDictionaryImpl) with a lexiconFilePath for which System.IO.File.Exists returns false — e.g. a typo'd path, a file deleted after registration, or a path in a location the process cannot see.","commonSituations":"Deploying an app that ships a .lex file but the file wasn't copied to the output directory; using a relative path whose current working directory differs; referencing a dictionary in a user profile that doesn't exist under another account; cleaning/publishing removing content files.","solutions":["Verify the lexicon file exists before adding it: check File.Exists(lexiconFilePath) and create or fix the path if false.","Ensure the dictionary file is included in the project as Content with CopyToOutputDirectory set, so it ships with the app.","Use an absolute path (Path.Combine(AppContext.BaseDirectory, \"dictionary.lex\")) instead of a relative one.","Catch ArgumentException around the dictionary registration and fall back to default spell-checking."],"exampleFix":"// before\nspeller.CustomDictionaries.Add(new Uri(relativeLexPath));\n// after\nstring lexPath = Path.Combine(AppContext.BaseDirectory, \"custom.lex\");\nif (!File.Exists(lexPath))\n    throw new FileNotFoundException(\"Custom dictionary missing\", lexPath);\nspeller.CustomDictionaries.Add(new Uri(lexPath));","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(lexiconFilePath) || !File.Exists(lexiconFilePath))\n    throw new FileNotFoundException($\"Lexicon not found: {lexiconFilePath}\");","typeGuard":null,"tryCatchPattern":"try { speller.CustomDictionaries.Add(dictUri); }\ncatch (ArgumentException ex) { Log.Warn($\"Dictionary skipped: {ex.Message}\"); }","preventionTips":["Always ship the lexicon as Content with CopyToOutputDirectory=CopyIfNewer","Resolve to absolute paths via AppContext.BaseDirectory before registering","Check File.Exists before every Add, not only at startup","Log the resolved path to catch CWD differences between dev and production"],"tags":["wpf","spellcheck","file-not-found","argumentexception"],"backgroundTag":"file-not-found","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}