iOfficeAI/OfficeCLI · error · InvalidOperationException
render exited {exitCode}
Error message
render exited {exitCode} What it means
Thrown by the render path when the child renderer exits with a non-zero code or produced no output file, and stderr was empty/blank. When stderr is non-empty the actual stderr text is used as the reason instead. The thrown message (either 'render exited <code>' or the trimmed stderr) is wrapped into the watch server's 500 JSON response.
Source
Thrown at src/officecli/Core/Watch/WatchServer.cs:2697
var drainOut = proc.StandardOutput.ReadToEndAsync(renderCts.Token);
try
{
await proc.WaitForExitAsync(renderCts.Token);
}
catch (OperationCanceledException)
{
try { proc.Kill(entireProcessTree: true); } catch { }
throw new InvalidOperationException("render timed out after 120s");
}
renderErr = await drainErr;
_ = await drainOut;
exitCode = proc.ExitCode;
}
}
if (exitCode != 0 || !File.Exists(tmpOut))
{
var reason = string.IsNullOrWhiteSpace(renderErr) ? $"render exited {exitCode}" : renderErr.Trim();
throw new InvalidOperationException(reason);
}
html = await File.ReadAllTextAsync(tmpOut, token);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
var sb500 = new StringBuilder("{\"error\":");
AppendJsonString(sb500, $"failed to render {Path.GetFileName(newPath)}: {ex.Message}");
sb500.Append('}');
await WriteJsonResponseAsync(stream, 500, "Internal Server Error", sb500.ToString(), token);
return;
}
finally
{
try { if (File.Exists(tmpOut)) File.Delete(tmpOut); } catch { }
}
// HTML in hand — swap state. Serialized so concurrent switches
// can't interleave their pipe/marker swaps.View on GitHub (pinned to 1ced45e900)
Solutions
- If stderr is available, read it — the server prefers stderr text over the bare exit code.
- Validate/open the source file in Office to confirm it is not corrupt.
- Ensure the renderer and its dependencies are installed in the environment.
- Reproduce the render standalone (`view <file> html --out x.html`) to capture the full stderr.
Example fix
# reproduce standalone to see the real error officecli view broken.pptx html --out /tmp/out.html # fix or replace the source, then the watch will re-render
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate the file opens before relying on watch render
if (!System.IO.File.Exists(path) || new System.IO.FileInfo(path).Length == 0)
throw new InvalidOperationException("source file missing or empty"); Try / catch
// The watch server returns HTTP 500 with {"error":"failed to render <file>: <reason>"}.
// Client: parse the JSON error; reproduce `view <file> html` to get full diagnostics. Prevention
- Reproduce failing renders standalone to capture complete stderr.
- Validate source files are well-formed Office documents before watching.
When it happens
Trigger: The `view <file> html` renderer failed: corrupt/unreadable source file, unsupported feature causing the renderer to error, missing dependency, or any non-zero exit with no output produced.
Common situations: Source file is malformed; renderer dependency missing in the environment; an unsupported OOXML construct the renderer chokes on; out-of-memory.
Related errors
- render timed out after 120s
- invalid_render
- native_unavailable
- mermaid failed to render: {ExtractMermaidMessage(dom)}
- mermaid rendered but produced no measurable svg viewBox.
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/3944d6be667b1e4f.
Report an issue: GitHub.