dotnet/wpf · error · ArgumentException

SR.Format(SR.CustomDictionaryFailedToLoadDictionaryUri…

Error message

SR.Format(SR.CustomDictionaryFailedToLoadDictionaryUri, lexiconFilePath)

What it means

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.

Solutions

  1. Verify the lexicon file exists at lexiconFilePath and is readable before constructing the speller.
  2. Inspect the InnerException of the ArgumentException for the actual load failure cause.
  3. Use an absolute, local path rather than a UNC/relative URI.
  4. Fix partial-trust permission grants so the file access demand succeeds (otherwise the original security exception surfaces instead).

Example fix

// before
var speller = new NLGSpellerInterop("\\\\server\\share\\custom.lex", false);
// after
string lex = @"C:\App\custom.lex";
if (File.Exists(lex) && File.CanRead(lex)) // check via try-open
{
    var speller = new NLGSpellerInterop(lex, false);
}
Defensive patterns

Strategy: validation

Validate before calling

bool lexiconReady = File.Exists(lexiconFilePath);
if (lexiconReady) { using var fs = File.OpenRead(lexiconFilePath); } // probe access

Try / catch

try { var s = new NLGSpellerInterop(path, false); }
catch (ArgumentException ex) { log(ex.InnerException); useDefaultDictionary(); }

Prevention

When it happens

Trigger: Constructing NLGSpellerInterop with a custom dictionary URI pointing to a file that is missing, unreadable, malformed, or inaccessible; inner exception carries the root cause.

Common situations: 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.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/55e8cf88ab3432a3. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs:977

            bool hasDemand = false;

            try
            {
                hasDemand = true;

                lexicon = NLGSpellerInterop.CreateLexicon();
                lexicon.ReadFrom(lexiconFilePath);
                _textChunk.get_Context(out textContext);
                textContext.AddLexicon(lexicon);
                exception = false;
            }
            catch (Exception e)
            {
                // We'll provide details of exception only if Demand to access lexiconFilePath was satisfied.
                // Otherwise it's a security concern to disclose this data.
                if (hasDemand)
                {
                    throw new ArgumentException(SR.Format(SR.CustomDictionaryFailedToLoadDictionaryUri, lexiconFilePath), e);
                }
                else
                {
                    throw;// Demand has failed so we're rethrowing security exception.
                }
            }
            finally
            {
                if ((exception) &&(lexicon != null))
                {
                    Marshal.ReleaseComObject(lexicon);
                }
                if (null != textContext)
                {
                    Marshal.ReleaseComObject(textContext);
                }
            }
            return lexicon;

View on GitHub (pinned to 81131a70a4)