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 ('<' = 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
- Check file permissions — ensure the process has read access (chmod/chown on Linux, ACL on Windows).
- Close any application that may have the file open exclusively, then retry.
- If the file is on a network/removable drive, verify the mount and copy it to local storage.
- 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
- Ensure the process has read permission on the multiple-replace file.
- Avoid opening the file in exclusive-lock applications (Excel, etc.) during conversion.
- Copy the rules file to local storage if it lives on a network share.
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
- Failed to parse multiple-replace XML at {path}: {ex.Message}
- Failed to parse multiple-replace JSON at {path}: {ex.Message
- File declares the Scenarist_SCC signature, but no valid capt
- Unable to determine subtitle format for: {filePath}
- Multiple-replace file not found: {path}
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/901715ef2990107b.
Report an issue: GitHub.