{"record":{"id":"55e8cf88ab3432a3","repo":"dotnet/wpf","slug":"sr-format-sr-customdictionaryfailedtoloaddictionaryuri","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/NLGSpellerInterop.cs","lineNumber":977,"sourceCode":"            bool hasDemand = false;\n\n            try\n            {\n                hasDemand = true;\n\n                lexicon = NLGSpellerInterop.CreateLexicon();\n                lexicon.ReadFrom(lexiconFilePath);\n                _textChunk.get_Context(out textContext);\n                textContext.AddLexicon(lexicon);\n                exception = false;\n            }\n            catch (Exception e)\n            {\n                // We'll provide details of exception only if Demand to access lexiconFilePath was satisfied.\n                // Otherwise it's a security concern to disclose this data.\n                if (hasDemand)\n                {\n                    throw new ArgumentException(SR.Format(SR.CustomDictionaryFailedToLoadDictionaryUri, lexiconFilePath), e);\n                }\n                else\n                {\n                    throw;// Demand has failed so we're rethrowing security exception.\n                }\n            }\n            finally\n            {\n                if ((exception) &&(lexicon != null))\n                {\n                    Marshal.ReleaseComObject(lexicon);\n                }\n                if (null != textContext)\n                {\n                    Marshal.ReleaseComObject(textContext);\n                }\n            }\n            return lexicon;","sourceCodeStart":959,"sourceCodeEnd":995,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs#L959-L995","documentation":"The NLGSpellerInterop constructor loads a custom dictionary from a lexicon file URI. Any exception during that load is wrapped in an ArgumentException with SR.CustomDictionaryFailedToLoadDictionaryUri and the failing path - but only if a security Demand for the file access already succeeded (hasDemand). If the demand failed, the original exception is rethrown unchanged to avoid disclosing the path.","triggerScenarios":"Constructing NLGSpellerInterop with a custom dictionary URI pointing to a file that is missing, unreadable, malformed, or inaccessible; inner exception carries the root cause.","commonSituations":"Deployed apps shipping a custom lexicon at a path that doesn't exist after install; network shares/UNC paths not reachable at runtime; partially-trusted apps whose FileIOPermission demand fails.","solutions":["Verify the lexicon file exists at lexiconFilePath and is readable before constructing the speller.","Inspect the InnerException of the ArgumentException for the actual load failure cause.","Use an absolute, local path rather than a UNC/relative URI.","Fix partial-trust permission grants so the file access demand succeeds (otherwise the original security exception surfaces instead)."],"exampleFix":"// before\nvar speller = new NLGSpellerInterop(\"\\\\\\\\server\\\\share\\\\custom.lex\", false);\n// after\nstring lex = @\"C:\\App\\custom.lex\";\nif (File.Exists(lex) && File.CanRead(lex)) // check via try-open\n{\n    var speller = new NLGSpellerInterop(lex, false);\n}","handlingStrategy":"validation","validationCode":"bool lexiconReady = File.Exists(lexiconFilePath);\nif (lexiconReady) { using var fs = File.OpenRead(lexiconFilePath); } // probe access","typeGuard":null,"tryCatchPattern":"try { var s = new NLGSpellerInterop(path, false); }\ncatch (ArgumentException ex) { log(ex.InnerException); useDefaultDictionary(); }","preventionTips":["Verify lexicon path exists at startup","Use absolute local paths, not UNC or relative URIs","Check InnerException for the true failure cause","Ensure code has FileIOPermission for the lexicon in partial-trust scenarios"],"tags":["spellcheck","file-io","argument-exception","wpf"],"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-21T21:30:21.729Z"}