{"record":{"id":"af1dc280d213fd99","repo":"iOfficeAI/OfficeCLI","slug":"pipe-communication-timed-out","errorCode":null,"errorMessage":"Pipe communication timed out","messagePattern":"Pipe communication timed out","errorType":"exception","errorClass":"TimeoutException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Watch/WatchNotifier.cs","lineNumber":312,"sourceCode":"                result = true;\n            }, PipeTimeout);\n            return result;\n        }\n        catch\n        {\n            return false;\n        }\n    }\n\n    /// <summary>\n    /// Run an action on a background thread with a timeout.\n    /// Prevents the calling thread from hanging if the pipe server dies mid-conversation.\n    /// </summary>\n    private static void RunWithTimeout(Action action, TimeSpan timeout)\n    {\n        var task = Task.Run(action);\n        if (!task.Wait(timeout))\n            throw new TimeoutException(\"Pipe communication timed out\");\n        task.GetAwaiter().GetResult(); // propagate exceptions\n    }\n}\n\n/// <summary>\n/// Message sent from command processes to the watch server via named pipe.\n/// </summary>\ninternal class WatchMessage\n{\n    /// <summary>\"replace\", \"add\", \"remove\", or \"full\"</summary>\n    public string Action { get; set; } = \"full\";\n\n    /// <summary>Slide number (0 for full refresh)</summary>\n    public int Slide { get; set; }\n\n    /// <summary>Single slide HTML fragment (for replace/add)</summary>\n    public string? Html { get; set; }\n","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Watch/WatchNotifier.cs#L294-L330","documentation":"Thrown by WatchNotifier.RunWithTimeout when a pipe action does not complete within the configured PipeTimeout. RunWithTimeout runs the action on a background Task and Task.Wait times out, throwing a TimeoutException so the calling thread never hangs if the watch server dies mid-conversation.","triggerScenarios":"The watch process is overloaded, deadlocked, or slow to respond to a mark/unmark/goto/get-marks/close pipe request; the named-pipe server accepted the connection but never replied within PipeTimeout.","commonSituations":"The watch process is busy rendering a large document; it crashed but the pipe endpoint lingers; system under heavy load; pipe buffer deadlock (writer/reader ordering).","solutions":["Check that the watch process is alive and responsive (IsWatching / the watch URL).","Retry the operation once; if it persists, restart the watch.","If rendering huge docs, allow more time or split the work."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm a watch is running before issuing pipe commands\nif (WatchNotifier.QueryMarksFull(filePath) is null) { /* no watch running; start one */ }","typeGuard":null,"tryCatchPattern":"TimeSpan backoff = TimeSpan.FromMilliseconds(250);\nfor (int attempt = 0; attempt < 3; attempt++)\n{\n    try { return WatchNotifier.AddMark(filePath, request); }\n    catch (TimeoutException) when (attempt < 2) { System.Threading.Thread.Sleep(backoff); backoff *= 2; }\n}\nreturn null; // give up after retries","preventionTips":["Guard each pipe call with a bounded retry and exponential backoff.","Keep watch documents reasonably sized to keep render/response fast.","Restart a wedged watch rather than hammering the pipe."],"tags":["watch","ipc","timeout","named-pipe"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}