dotnet/wpf · error · InvalidOperationException

SR.FileNameMustNotBeNull

Error message

SR.FileNameMustNotBeNull

What it means

OpenFileDialog.OpenFile opens a stream on the file the user selected (CriticalItemName). If the dialog was never successfully completed or returned no filename, the property is null/empty and an InvalidOperationException is thrown rather than attempting to open an invalid path.

Solutions

  1. Call ShowDialog() first and only call OpenFile() when it returned true
  2. Check string.IsNullOrEmpty(dlg.FileName) before calling OpenFile as a defensive guard
  3. If the dialog may be cancelled, handle the cancellation path instead of opening a stream
  4. For multiple selections use FileNames/OpenFiles with the same checks

Example fix

// before
var dlg = new OpenFileDialog();
using var s = dlg.OpenFile();
// after
var dlg = new OpenFileDialog();
if (dlg.ShowDialog() == true)
{
    using var s = dlg.OpenFile();
}
Defensive patterns

Strategy: validation

Validate before calling

if (dlg.ShowDialog() != true || string.IsNullOrEmpty(dlg.FileName))
    return; // user cancelled or nothing selected
using var s = dlg.OpenFile();

Type guard

bool HasSelection(OpenFileDialog d) => d.ShowDialog() == true && !string.IsNullOrEmpty(d.FileName);

Try / catch

try { using var s = dlg.OpenFile(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("null"))
{
    // dialog not completed; treat as cancellation
}

Prevention

When it happens

Trigger: Calling OpenFile() without first calling ShowDialog and checking the result equals true; calling it after the user cancelled the dialog; deserializing/reusing an OpenFileDialog instance that has no cached filename.

Common situations: Assuming ShowDialog succeeded without checking the nullable bool return; calling OpenFile in code paths that run even when the user pressed Cancel; using a fresh OpenFileDialog that was never shown.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/OpenFileDialog.cs:71

        /// <summary>
        ///  Opens the file selected by the user with read-only permission,
        ///  whether or not the Read Only checkbox is checked in the dialog.
        /// </summary>
        ///  The filename used to open the file is the first element of the
        ///  FileNames array.
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if there are no filenames stored in the OpenFileDialog.
        /// </exception>
        public Stream OpenFile()
        {
            string filename = CriticalItemName;

            // If we got an empty or null filename, throw an exception to
            // tell the user we don't have any files to open.
            if (string.IsNullOrEmpty(filename))
            {
                throw new InvalidOperationException(SR.FileNameMustNotBeNull);
            }

            return new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        /// <summary>
        ///  Opens the files selected by the user with read-only permission and
        ///  returns an array of streams, one per file.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if there are no filenames stored in the OpenFileDialog
        /// </exception>
        public Stream[] OpenFiles()
        {
            // Cache ItemNames to avoid perf issues as per
            // FxCop #CA1817
            string[] cachedFileNames = CloneItemNames();

View on GitHub (pinned to 81131a70a4)