{"record":{"id":"b7bf82e5ae3b597b","repo":"iOfficeAI/OfficeCLI","slug":"render-timed-out-after-120s","errorCode":null,"errorMessage":"render timed out after 120s","messagePattern":"render timed out after 120s","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Watch/WatchServer.cs","lineNumber":2687,"sourceCode":"\n                string renderErr = \"\";\n                int exitCode = -1;\n                using (var proc = System.Diagnostics.Process.Start(psi))\n                {\n                    if (proc != null)\n                    {\n                        using var renderCts = CancellationTokenSource.CreateLinkedTokenSource(token);\n                        renderCts.CancelAfter(TimeSpan.FromSeconds(120));\n                        var drainErr = proc.StandardError.ReadToEndAsync(renderCts.Token);\n                        var drainOut = proc.StandardOutput.ReadToEndAsync(renderCts.Token);\n                        try\n                        {\n                            await proc.WaitForExitAsync(renderCts.Token);\n                        }\n                        catch (OperationCanceledException)\n                        {\n                            try { proc.Kill(entireProcessTree: true); } catch { }\n                            throw new InvalidOperationException(\"render timed out after 120s\");\n                        }\n                        renderErr = await drainErr;\n                        _ = await drainOut;\n                        exitCode = proc.ExitCode;\n                    }\n                }\n                if (exitCode != 0 || !File.Exists(tmpOut))\n                {\n                    var reason = string.IsNullOrWhiteSpace(renderErr) ? $\"render exited {exitCode}\" : renderErr.Trim();\n                    throw new InvalidOperationException(reason);\n                }\n                html = await File.ReadAllTextAsync(tmpOut, token);\n            }\n            catch (Exception ex) when (ex is not OperationCanceledException)\n            {\n                var sb500 = new StringBuilder(\"{\\\"error\\\":\");\n                AppendJsonString(sb500, $\"failed to render {Path.GetFileName(newPath)}: {ex.Message}\");\n                sb500.Append('}');","sourceCodeStart":2669,"sourceCodeEnd":2705,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Watch/WatchServer.cs#L2669-L2705","documentation":"Thrown by WatchServer's render path when the child `view <file> html` process does not exit within 120 seconds. A linked CancellationTokenSource cancels after 120s; on OperationCanceledException the process tree is killed and this InvalidOperationException is thrown, which the caller wraps into a 500 response. It bounds watch latency so a wedged render cannot stall the server.","triggerScenarios":"The document being rendered is very large/complex and the renderer exceeds 120s; the renderer process hung/deadlocked; the system is heavily loaded.","commonSituations":"Huge presentations/documents; a renderer with a pending font/asset fetch blocking it; resource-constrained host.","solutions":["Render a smaller or simpler document.","Retry once; transient load can cause a one-off overrun.","Check the renderer is not blocked on a network/font fetch."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// No pre-check; mitigate by keeping documents renderable in well under 120s.\n// If you control the source, split very large decks into smaller files.","typeGuard":null,"tryCatchPattern":"// The watch server already returns HTTP 500 with {\"error\":\"...timed out...\"}.\n// Client: retry the view/refresh once; if it persists, reduce document size.","preventionTips":["Keep documents compact (fewer slides/smaller images) so renders finish fast.","Treat a render-timeout response as transient and retry once.","Watch renderer stderr for clues (font/asset stalls)."],"tags":["watch","render","timeout","performance"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}