DevToys-app/DevToys · error · FileNotFoundException

Unable to find the indicated file.

Error message

Unable to find the indicated file.

What it means

Thrown by the SimpleSandboxedFileReader constructor (SandboxedFileReader.FromFileInfo path) when the supplied FileInfo reports Exists == false at construction time. SimpleSandboxedFileReader wraps a read-only, share-read file access (FileMode.Open, FileShare.Read, async/sequential). Because FileInfo caches its Exists value, a stale FileInfo from before the file was deleted will still trip this guard.

Source

Thrown at src/app/dev/DevToys.Api/Core/SimpleSandboxedFileReader.cs:21

/// <summary>
/// Represents a read-only access to a file on the file system.
/// </summary>
/// <remarks>
/// The file can be read and accessed multiple times in parallel.
/// In some cases, the file's resulting stream is non-seekable.
/// Disposing the <see cref="SandboxedFileReader"/> will close the access to the file.
/// </remarks>
[DebuggerDisplay($"FileName = {{{nameof(FileName)}}}")]
internal sealed class SimpleSandboxedFileReader : SandboxedFileReader
{
    private readonly FileInfo _fileInfo;

    internal SimpleSandboxedFileReader(FileInfo fileInfo)
        : base(fileInfo.Name)
    {
        if (!fileInfo.Exists)
        {
            throw new FileNotFoundException("Unable to find the indicated file.", fileInfo.FullName);
        }

        _fileInfo = fileInfo;
    }

    protected override ValueTask<Stream> OpenReadFileAsync(CancellationToken cancellationToken)
    {
        if (!_fileInfo.Exists)
        {
            throw new FileNotFoundException("Unable to find the indicated file.", _fileInfo.FullName);
        }

        return ValueTask.FromResult(
            (Stream)new FileStream(
                _fileInfo.FullName,
                FileMode.Open,
                FileAccess.Read,
                FileShare.Read,

View on GitHub (pinned to 7e12df8448)

Solutions

  1. Call fileInfo.Refresh() right before constructing the reader so Exists reflects current disk state.
  2. Guard with `if (!fileInfo.Exists) return;` (or reprompt) before FromFileInfo.
  3. For user-picked files, re-validate existence immediately before opening and surface a friendly message if missing.
  4. Wrap FromFileInfo in try/catch (FileNotFoundException) and recover by reprompting or skipping.

Example fix

// before
var reader = SandboxedFileReader.FromFileInfo(fileInfo);

// after
fileInfo.Refresh();
if (!fileInfo.Exists)
{
    // reprompt / log / abort
    return;
}
var reader = SandboxedFileReader.FromFileInfo(fileInfo);
Defensive patterns

Strategy: validation

Validate before calling

// Refresh defeats FileInfo's cached Exists before constructing the reader.
fileInfo.Refresh();
if (!fileInfo.Exists)
{
    // file gone — reprompt / abort
    return;
}
SandboxedFileReader reader = SandboxedFileReader.FromFileInfo(fileInfo);

Try / catch

try
{
    SandboxedFileReader reader = SandboxedFileReader.FromFileInfo(fileInfo);
}
catch (FileNotFoundException ex)
{
    // source file vanished before construction — reprompt the user or skip
}

Prevention

When it happens

Trigger: Constructing SimpleSandboxedFileReader (via SandboxedFileReader.FromFileInfo) with a FileInfo whose underlying file was deleted, moved, or never written; passing a FileInfo captured long before use without calling Refresh(); a picked file the user removed from disk between selection and open.

Common situations: User picks a file in the file dialog then deletes/renames it externally before the read; a temp file cleaned up by the OS or another process; cross-device path resolution where the FileInfo FullName points somewhere unreachable.

Related errors


AI-assisted analysis of DevToys-app/DevToys@7e12df8448 (2026-08-13). Data as JSON: /api/errors/b60fee6fc3ca372a. Report an issue: GitHub.