SubtitleEdit/subtitleedit · error · FileNotFoundException
Multiple-replace file not found: {path}
Error message
Multiple-replace file not found: {path} What it means
Thrown by MultipleReplaceLoader.Apply when the multiple-replace rules file does not exist (File.Exists returns false). Apply loads and applies active rules from the file to a subtitle — without the file there is nothing to apply. The exception is a FileNotFoundException with the path as FileName. Note: LoadRules (the lower-level method) does its own File.Exists check via ReadAllText's exception path, but Apply checks first for a clean error.
Source
Thrown at src/seconv/Core/MultipleReplaceLoader.cs:392
public string ReplaceWith { get; set; } = string.Empty;
public string? Description { get; set; }
public bool IsActive { get; set; }
public string Type { get; set; } = string.Empty;
}
}
/// <summary>
/// Loads + applies all active rules from <paramref name="path"/> to <paramref name="subtitle"/>.
/// The file may be the legacy SE4 <c>MultipleSearchAndReplaceGroups</c> XML, or the SE5
/// GUI's exported <c>.template</c> JSON or <c>.csv</c> (Tools > Multiple replace >
/// export). Format is chosen by extension, then by content sniffing. Returns the number of
/// paragraphs whose text was modified.
/// </summary>
public static int Apply(Subtitle subtitle, string path)
{
if (!File.Exists(path))
{
throw new FileNotFoundException($"Multiple-replace file not found: {path}", path);
}
var rules = LoadRules(path);
if (rules.Count == 0)
{
return 0;
}
// Pre-compile rule patterns once (not per-paragraph):
// - RegularExpression rules use the user pattern with RegexOptions.Multiline so ^/$
// anchors match at every line boundary, matching the UI (MultipleReplaceViewModel
// compiles with Compiled | Multiline).
// - Normal (case-insensitive literal) rules compile an escaped, IgnoreCase pattern
// so the per-paragraph loop no longer re-escapes and re-parses on every line.
// A rule with an invalid/empty pattern is left out here so it's skipped entirely.
var compiledRegex = new Dictionary<Rule, Regex>();
foreach (var rule in rules)
{View on GitHub (pinned to 17a9f07487)
Solutions
- Verify the path with File.Exists before calling Apply.
- Resolve relative paths to absolute with Path.GetFullPath against the intended base directory.
- Check for typos, trailing spaces, or shell-quoting issues in the path argument.
Example fix
// before
MultipleReplaceLoader.Apply(subtitle, rulesPath);
// after
if (!File.Exists(rulesPath))
throw new FileNotFoundException($"Multiple-replace file not found: {rulesPath}");
MultipleReplaceLoader.Apply(subtitle, rulesPath); Defensive patterns
Strategy: validation
Validate before calling
if (!File.Exists(path))
throw new FileNotFoundException($"Multiple-replace file not found: {path}", path);
MultipleReplaceLoader.Apply(subtitle, path); Type guard
static bool IsReplaceFileReadable(string path) => File.Exists(path);
Try / catch
try { MultipleReplaceLoader.Apply(subtitle, path); }
catch (FileNotFoundException ex) when (ex.Message.Contains("Multiple-replace file not found"))
{ /* report missing rules file, check path/spelling */ } Prevention
- Validate File.Exists for the rules file path before calling Apply.
- Resolve relative paths to absolute with Path.GetFullPath.
- Store rules files in a known, version-controlled location and reference by absolute path.
When it happens
Trigger: Calling Apply(subtitle, path) where path does not resolve to an existing file. The path may be a typo, a relative path from the wrong CWD, or reference a file that was moved/deleted.
Common situations: CLI --multiple-replace with a mistyped path; a config referencing a rules file that was moved; a batch script using a relative path that breaks when CWD changes.
Related errors
- Subtitle file not found: {filePath}
- EBU header file not found: {ebuHeaderFile}
- ASSA style file not found: {assaStyleFile}
- OCR model file not found: {name}
- Failed to parse multiple-replace XML at {path}: {ex.Message}
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/358a49aedc907120.
Report an issue: GitHub.