{"record":{"id":"d561e2f425209c78","repo":"iOfficeAI/OfficeCLI","slug":"error","errorCode":null,"errorMessage":"{error}","messagePattern":"\\{error\\}","errorType":"exception","errorClass":"MarkRejectedException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Watch/WatchNotifier.cs","lineNumber":182,"sourceCode":"                writer.WriteLine(\"mark \" + payload);\n                writer.Flush();\n\n                using var reader = new StreamReader(client, noBom, detectEncodingFromByteOrderMarks: false, leaveOpen: true);\n                var responseLine = reader.ReadLine();\n                if (string.IsNullOrEmpty(responseLine)) { result = null; return; }\n                var resp = JsonSerializer.Deserialize(responseLine, WatchMarkJsonContext.Default.MarkResponse);\n                // BUG-FUZZER-R3-M01: use IsNullOrWhiteSpace for symmetry with the\n                // server-side path/color validation. A whitespace-only error string\n                // would otherwise spuriously throw MarkRejectedException.\n                if (!string.IsNullOrWhiteSpace(resp?.Error)) { error = resp!.Error; return; }\n                result = string.IsNullOrEmpty(resp?.Id) ? null : resp.Id;\n            }, PipeTimeout);\n        }\n        catch\n        {\n            return null; // no watch running, or pipe failure\n        }\n        if (error != null) throw new MarkRejectedException(error);\n        return result;\n    }\n\n    /// <summary>\n    /// Remove marks from the running watch process. Returns count removed,\n    /// or null if no watch is running.\n    /// </summary>\n    public static int? RemoveMarks(string filePath, UnmarkRequest request)\n    {\n        try\n        {\n            int? result = null;\n            RunWithTimeout(() =>\n            {\n                var pipeName = WatchServer.GetWatchPipeName(filePath);\n                using var client = new NamedPipeClientStream(\".\", pipeName, PipeDirection.InOut);\n                client.Connect(200);\n","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Watch/WatchNotifier.cs#L164-L200","documentation":"Thrown by WatchNotifier.AddMark when the running watch server returned a non-blank Error in its MarkResponse. The CLI distinguishes a pipe/timeout failure (returns null = 'no watch running') from a real server-side rejection (throws MarkRejectedException) so the user sees the actual cause (e.g. invalid regex, bad color/path) instead of an empty id being treated as success. BUG-FUZZER-R3-M01 made the check IsNullOrWhiteSpace so a whitespace-only error no longer spuriously throws.","triggerScenarios":"Calling AddMark (or the mark command) while a watch is running, with a MarkRequest the server rejects: an invalid/uncompilable regex find string, an unsupported color, a malformed path/selector, or any server-side validation failure that populates the Error field.","commonSituations":"User passes an invalid regex (e.g. unbalanced '('), a color the server does not accept, or a malformed highlight path; the watch server's validation rejects it and echoes the reason.","solutions":["Read the exception Message — it carries the server's verbatim Error reason.","Fix the offending field: correct the regex, use a supported color, fix the path/selector.","Retry the mark once the input is valid."],"exampleFix":"// before\nvar id = WatchNotifier.AddMark(file, new MarkRequest { Find = \"(unclosed\", Color = \"red\" });\n// after\nvar id = WatchNotifier.AddMark(file, new MarkRequest { Find = \"\\\\(closed\\\\)\", Color = \"red\" });","handlingStrategy":"try-catch","validationCode":"// Validate the find string as a regex before sending if regex=true\nif (request.Regex && !IsValidRegex(request.Find))\n    throw new InvalidOperationException(\"invalid regex in mark request\");\nstatic bool IsValidRegex(string p) { try { _ = new System.Text.RegularExpressions.Regex(p); return true; } catch { return false; } }","typeGuard":null,"tryCatchPattern":"string? id;\ntry { id = WatchNotifier.AddMark(filePath, request); }\ncatch (MarkRejectedException ex)\n{ /* ex.Message is the watch server's rejection reason; fix and retry */ id = null; }\nif (id == null) { /* no watch running, or rejected */ }","preventionTips":["Distinguish null (no watch) from MarkRejectedException (rejected) in your handler.","Pre-validate regex/color inputs before they reach the pipe."],"tags":["watch","mark","validation","ipc"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}