SubtitleEdit/subtitleedit · error · InvalidDataException

Failed to read multiple-replace file at {path}: {ex.Message}

Error message

Failed to read multiple-replace file at {path}: {ex.Message}

What it means

Wrapped exception thrown by MultipleReplaceLoader.LoadRules when File.ReadAllText(path) throws — the file passed the caller's existence check (or LoadRules was called directly) but the read itself failed (I/O error, permission denied, disk error, file locked). The original exception is preserved as the InnerException of an InvalidDataException with the path and original message.

Source

Thrown at src/seconv/Core/MultipleReplaceLoader.cs:66

        public string? Description { get; set; }
    }

    /// <summary>
    /// Reads the active rules from an XML / JSON (.template) / CSV multiple-replace file into the
    /// flat rule list the apply loop uses. Format is chosen by extension, falling back to sniffing
    /// the first non-whitespace character ('&lt;' = XML, '{' = JSON, else CSV).
    /// </summary>
    public static List<Rule> LoadRules(string path)
    {
        var ext = Path.GetExtension(path).ToLowerInvariant();
        string content;
        try
        {
            content = File.ReadAllText(path);
        }
        catch (Exception ex)
        {
            throw new InvalidDataException($"Failed to read multiple-replace file at {path}: {ex.Message}", ex);
        }

        var firstChar = content.AsSpan().TrimStart().Length > 0 ? content.AsSpan().TrimStart()[0] : '\0';
        var isXml = ext == ".xml" || (ext != ".csv" && ext != ".json" && ext != ".template" && firstChar == '<');
        var isJson = ext == ".json" || ext == ".template" || (ext != ".xml" && ext != ".csv" && firstChar == '{');

        if (isXml)
        {
            return LoadXmlRules(content, path);
        }

        if (isJson)
        {
            return LoadCategoryItemRules(ParseJson(content, path));
        }

        return LoadCategoryItemRules(CsvRules.Parse(content));
    }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Check file permissions — ensure the process has read access (chmod/chown on Linux, ACL on Windows).
  2. Close any application that may have the file open exclusively, then retry.
  3. If the file is on a network/removable drive, verify the mount and copy it to local storage.
  4. Catch InvalidDataException and inspect InnerException for the underlying I/O cause.
Defensive patterns

Strategy: try-catch

Try / catch

try { var rules = MultipleReplaceLoader.LoadRules(path); }
catch (InvalidDataException ex) when (ex.Message.Contains("Failed to read multiple-replace file"))
{
    // ex.InnerException has the underlying IOException/UnauthorizedAccessException
    var ioCause = ex.InnerException;
    // Report I/O or permission issue to user
}

Prevention

When it happens

Trigger: The multiple-replace file exists but is unreadable: locked by another process, access denied (ACL/permission), on an unmounted/removable drive, or a disk I/O error mid-read. LoadRules calls File.ReadAllText which surfaces these as IOException/UnauthorizedAccessException.

Common situations: The file is open in another application with an exclusive lock (e.g. Excel for CSV); the process runs under a user without read permission; a network share dropped mid-read; the file was created but not flushed/closed by the writer.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/901715ef2990107b. Report an issue: GitHub.