{"record":{"id":"901715ef2990107b","repo":"SubtitleEdit/subtitleedit","slug":"failed-to-read-multiple-replace-file-at-path-e","errorCode":null,"errorMessage":"Failed to read multiple-replace file at {path}: {ex.Message}","messagePattern":"Failed to read multiple-replace file at (.+?): (.+?)","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"src/seconv/Core/MultipleReplaceLoader.cs","lineNumber":66,"sourceCode":"        public string? Description { get; set; }\n    }\n\n    /// <summary>\n    /// Reads the active rules from an XML / JSON (.template) / CSV multiple-replace file into the\n    /// flat rule list the apply loop uses. Format is chosen by extension, falling back to sniffing\n    /// the first non-whitespace character ('&lt;' = XML, '{' = JSON, else CSV).\n    /// </summary>\n    public static List<Rule> LoadRules(string path)\n    {\n        var ext = Path.GetExtension(path).ToLowerInvariant();\n        string content;\n        try\n        {\n            content = File.ReadAllText(path);\n        }\n        catch (Exception ex)\n        {\n            throw new InvalidDataException($\"Failed to read multiple-replace file at {path}: {ex.Message}\", ex);\n        }\n\n        var firstChar = content.AsSpan().TrimStart().Length > 0 ? content.AsSpan().TrimStart()[0] : '\\0';\n        var isXml = ext == \".xml\" || (ext != \".csv\" && ext != \".json\" && ext != \".template\" && firstChar == '<');\n        var isJson = ext == \".json\" || ext == \".template\" || (ext != \".xml\" && ext != \".csv\" && firstChar == '{');\n\n        if (isXml)\n        {\n            return LoadXmlRules(content, path);\n        }\n\n        if (isJson)\n        {\n            return LoadCategoryItemRules(ParseJson(content, path));\n        }\n\n        return LoadCategoryItemRules(CsvRules.Parse(content));\n    }","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/seconv/Core/MultipleReplaceLoader.cs#L48-L84","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { var rules = MultipleReplaceLoader.LoadRules(path); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"Failed to read multiple-replace file\"))\n{\n    // ex.InnerException has the underlying IOException/UnauthorizedAccessException\n    var ioCause = ex.InnerException;\n    // Report I/O or permission issue to user\n}","preventionTips":["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."],"tags":["multiple-replace","io-error","file-access","parse-failure","subtitles"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}