iOfficeAI/OfficeCLI · error · CliException
max_depth_exceeded
max_depth_exceeded
Error message
Document nesting exceeds the maximum supported depth (~{MaxRecursionDepth}); the file may be malformed or crafted to exhaust resources. What it means
EnsureDepth guards recursive document parsing against two risks: exceeding MaxRecursionDepth (256) and running out of stack. It throws a CliException (code 'max_depth_exceeded') when either depth > 256 or RuntimeHelpers.TryEnsureSufficientExecutionStack() reports insufficient remaining stack. The probe adapts to the actual thread stack rather than a fixed number, mirroring the FormulaEvaluator guard.
Source
Thrown at src/officecli/Core/DocumentLimits.cs:117
/// renderer has descended too far. Call at the top of each recursive method
/// so a maliciously deep document fails with a clean error instead of an
/// uncatchable StackOverflowException.
///
/// Two complementary guards, because the safe depth depends on thread stack
/// size (the 8 MB main thread tolerates far deeper recursion than the ~1 MB
/// thread-pool threads the resident/watch server uses, and renderer frames
/// are large):
/// - <see cref="MaxRecursionDepth"/> bounds the worst-case time/O(n^2) cost
/// on any stack;
/// - <see cref="RuntimeHelpers.TryEnsureSufficientExecutionStack"/> probes
/// the *actual* remaining stack and trips before a real overflow, so the
/// guard adapts to whatever thread the call runs on (mirrors the probe in
/// <see cref="OfficeCli.Core.Formula.FormulaEvaluator"/>).
/// </summary>
public static void EnsureDepth(int depth)
{
if (depth > MaxRecursionDepth || !RuntimeHelpers.TryEnsureSufficientExecutionStack())
throw new CliException(
$"Document nesting exceeds the maximum supported depth (~{MaxRecursionDepth}); " +
"the file may be malformed or crafted to exhaust resources.")
{
Code = "max_depth_exceeded",
Suggestion = "Verify the document is a genuine Office file."
};
}
}
View on GitHub (pinned to 1ced45e900)
Solutions
- Verify the file is a genuine Office document — a crafted file is the most common cause.
- If the file is legitimately deep, run parsing on a thread with a larger stack (e.g. a dedicated thread with a bigger stackSize) so the stack probe doesn't trip early.
- Catch CliException with Code == 'max_depth_exceeded' and report it as 'unsupported document' rather than crashing the host process.
- If authoring the file, flatten excessive nesting.
Example fix
// before — parse on a thread-pool thread (small stack), trips the probe early var doc = Task.Run(() => parser.Parse(stream)).Result; // after — run on a dedicated thread with a large stack so the 256 depth bound governs var t = new Thread(() => doc = parser.Parse(stream), 0, true, (int)(8 * 1024 * 1024)); t.Start(); t.Join();
Defensive patterns
Strategy: validation
Validate before calling
// Before recursing, surface a clean error instead of letting the guard throw deep in the stack DocumentLimits.EnsureDepth(currentDepth); // throws CliException(Code="max_depth_exceeded")
Try / catch
try { parser.Parse(stream); }
catch (CliException ex) when (ex.Code == "max_depth_exceeded")
{
// report unsupported/crafted document; do not crash the host
logger.Warn("Document nesting too deep or crafted; rejected. {Suggestion}", ex.Suggestion);
} Prevention
- Run deep-parse work on a thread with a large stack (e.g. 8MB) so the stack probe isn't the bottleneck.
- Catch CliException with Code 'max_depth_exceeded' explicitly and report it.
- Treat untrusted Office files as potentially crafted; the guard exists to stop resource exhaustion.
When it happens
Trigger: Deeply nested OOXML structures (nested groups, nested tables, recursive containers) push the parser's recursion depth past 256, or the thread's stack is low (resident/watch server thread-pool threads have smaller stacks) so TryEnsureSufficientExecutionStack trips first.
Common situations: A malformed or crafted Office file designed as a zip-bomb/stack-exhaustion vector; a genuinely pathological deeply-nested document; running the parser on a thread-pool thread (smaller stack) where 256 isn't even reached before the stack probe trips.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid {contextKey} URL scheme '{scheme}:': only http, http
- Image file '{path}' has extension .{ext} but magic bytes ind
- dump_reader_not_found
- corrupt_batch
- plugin_command_failed
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/e60b2e2fefd2137f.
Report an issue: GitHub.