# OfficeCLI Error Recovery: A Complete Guide to Structured Error Codes

> Master OfficeCLI error recovery with structured error codes. Learn to implement deterministic error handling for automation and AI, avoiding fragile string matching. Improve your scripts today.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-08-06

---

**OfficeCLI uses machine-readable error envelopes with stable `code` fields generated by `OutputFormatter.InferErrorCode`, enabling deterministic error handling for automation scripts and AI agents without fragile string matching.**

The iOfficeAI/OfficeCLI repository implements a robust error recovery system that transforms opaque exception messages into structured, actionable codes. Unlike traditional CLIs that output human-readable text requiring regex parsing, OfficeCLI provides a consistent JSON envelope format accessible via `OutputFormatter.WrapEnvelopeError`, allowing programmatic detection of specific failure modes ranging from missing slides to invalid file paths.

## How Structured Error Codes Work

When an operation fails, OfficeCLI captures the exception and routes it through a centralized inference engine. The system distinguishes between explicit `CliException` types—which carry pre-defined codes—and unknown exceptions that require pattern matching.

### The CliException Foundation

In [`src/officecli/Core/CliException.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/CliException.cs) (lines 17-18), the base exception class defines the contract for structured failures:

```csharp
public string Code { get; }
public string Suggestion { get; }
public string Help { get; }
public string[] ValidValues { get; }

```

When code throws a `CliException`, the error code is already specified. For all other exception types, `OutputFormatter.InferErrorCode` creates an `ErrorResult` and delegates to `EnrichFromMessage` to derive the appropriate code.

### Pattern Matching in EnrichFromMessage

The `EnrichFromMessage` method in [`src/officecli/Core/OutputFormatter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/OutputFormatter.cs) (lines 317-596) implements exhaustive pattern matching against exception messages. This mapping covers specific Office document errors, filesystem failures, and validation issues.

**Key pattern mappings include:**

- **Slide index errors:** `"Slide 50 not found (total: 8)"` → `not_found` (includes valid range suggestion)
- **Missing elements:** `"Path not found:"` or `"Sheet not found:"` → `not_found`
- **Invalid identifiers:** `"Unknown part: … . Available: …"` → `invalid_path` (populates `validValues`)
- **Format issues:** `"Unsupported file type:"` → `unsupported_type`
- **Semantic errors:** Any message starting with `"Invalid "` → `invalid_value`
- **Duplicates:** `"already exists"` → `duplicate_name`
- **Property validation:** `"requires a '<prop>' property"` → `missing_property`
- **Filesystem:** `FileNotFoundException`, `UnauthorizedAccessException`, `DirectoryNotFoundException` → `file_not_found` or `io_error`
- **Data format:** `"batch item[…] is null"` → `invalid_json`
- **XPath:** `"Expression must evaluate"` → `invalid_xpath`

The method guarantees a code assignment: if no pattern matches, lines 713-715 assign `internal_error` as the fallback.

## Complete Error Code Reference

OfficeCLI exposes twelve distinct error codes through the `ErrorResult` class:

| Code | Trigger Condition | Typical Resolution |
|------|-------------------|-------------------|
| `not_found` | Requested slide, sheet, or element does not exist | Check index ranges or element names |
| `invalid_path` | Identifier unknown but alternatives exist | Use one of the `validValues` provided |
| `unsupported_type` | File format incompatible with operation | Convert to supported format |
| `invalid_value` | Syntactically valid but semantically illegal input | Correct numeric ranges or color values |
| `duplicate_name` | Resource creation conflict | Rename or remove existing resource |
| `unsupported_property` | Backend cannot handle specified properties | Remove unsupported flags |
| `missing_property` | Required parameter absent | Add the specified property |
| `file_not_found` | Filesystem-level file missing | Verify paths and permissions |
| `io_error` | Read/write failures, authorization issues | Check disk space and access rights |
| `invalid_json` | Malformed batch payload | Validate JSON structure |
| `invalid_xpath` | Malformed XPath expression | Correct query syntax |
| `internal_error` | Unexpected/unmapped exception | Report as potential bug |

## JSON Error Envelope Format

The `WrapEnvelopeError` method produces a consistent envelope used across single commands and batch operations:

```json
{
  "success": false,
  "data": {
    "error": "Slide 50 not found (total: 8)",
    "code": "not_found",
    "suggestion": "Valid Slide index range: 1-8",
    "validValues": null
  },
  "warnings": []
}

```

**Envelope fields:**
- `success`: Boolean indicating business-level failure
- `data`: Contains `ErrorResult` with error message, structured code, help text, and valid alternatives
- `warnings`: Optional array from `WarningContext` containing non-fatal issues

## Practical Implementation Examples

### Shell Script Error Handling

Parse structured errors in bash without fragile grep operations:

```bash
#!/usr/bin/env bash
result=$(officecli view mydoc.docx --view html --json 2>/dev/null)
code=$(jq -r '.data.code // empty' <<<"$result")

if [[ $code == "not_found" ]]; then
  echo "Requested element does not exist – check the index range."
elif [[ $code == "invalid_value" ]]; then
  echo "Bad value supplied – see suggestion:"
  jq -r '.data.suggestion // empty' <<<"$result"
elif [[ $code == "file_not_found" ]]; then
  echo "Input document missing. Check path and permissions."
fi

```

### .NET Client Integration

Handle specific failure modes using pattern matching on `CliException.Code`:

```csharp
try
{
    var cli = new OfficeCliClient();
    cli.RunCommand("add slide 50 --from template.pptx");
}
catch (CliException ex) when (ex.Code == "duplicate_name")
{
    Console.WriteLine($"Slide already exists. Help: {ex.Help}");
}
catch (CliException ex) when (ex.Code == "not_found")
{
    Console.WriteLine($"Invalid index. Suggestion: {ex.Suggestion}");
}
catch (Exception ex)
{
    // Infer code for non-CliException errors
    var code = OutputFormatter.InferErrorCode(ex);
    Console.WriteLine($"CLI failed with code: {code}");
}

```

### Batch Processing with Per-Item Codes

In [`src/officecli/CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Batch.cs) (line 87), `InferErrorCode` populates individual result objects, enabling granular error handling:

```json
{
  "success": false,
  "data": [
    { "index": 0, "success": true, "item": { "slide": 1 } },
    { "index": 1, "success": false, "item": {}, 
      "error": "Slide 5 not found", 
      "code": "not_found",
      "suggestion": "Valid range: 1-3" }
  ]
}

```

This structure allows batch consumers to iterate results and apply specific recovery logic per item rather than failing the entire operation.

## Key Source Files and Architecture

Understanding the codebase organization helps when extending or debugging error handling:

- **[`src/officecli/Core/OutputFormatter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/OutputFormatter.cs)**: Central inference engine containing `InferErrorCode`, `EnrichFromMessage`, and `WrapEnvelopeError`
- **[`src/officecli/Core/CliException.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/CliException.cs)**: Exception type carrying explicit `Code`, `Suggestion`, `Help`, and `ValidValues` properties
- **[`src/officecli/CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Batch.cs)**: Applies per-item error codes in batch mode (line 87)
- **[`src/officecli/Help/SchemaHelpRenderer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Help/SchemaHelpRenderer.cs)**: Generates documentation referencing the same error codes for consistency

These files collectively define the **structured error-recovery contract** used throughout the CLI, ensuring that whether failures originate from document validation, filesystem access, or JSON parsing, they surface through a uniform programmatic interface.

## Summary

- **`WrapEnvelopeError`** generates consistent JSON envelopes containing error details, codes, and suggestions
- **`InferErrorCode`** maps unknown exceptions to stable codes via exhaustive pattern matching in `EnrichFromMessage`
- **`CliException`** enables explicit error classification with additional context like `validValues` and `help` text
- **Batch operations** preserve error codes per item, allowing partial success handling instead of all-or-nothing failures
- **Twelve distinct codes** cover filesystem, validation, XPath, JSON, and semantic Office document errors

## Frequently Asked Questions

### How does OfficeCLI determine which error code to use?

The system checks if the exception is a `CliException` first; if so, it uses the pre-defined `Code` property. Otherwise, `OutputFormatter.InferErrorCode` creates an `ErrorResult` and calls `EnrichFromMessage` to pattern-match the exception message against known substrings, assigning `internal_error` only if no patterns match.

### What is the difference between `not_found` and `file_not_found`?

`not_found` indicates a logical missing element within a document (slide 50 in an 8-slide deck, missing sheet name), while `file_not_found` specifically handles filesystem-level `FileNotFoundException` or path strings starting with `"File not found:"`. The former includes valid ranges in suggestions; the latter indicates the input document itself is inaccessible.

### How do batch operations handle mixed success/failure scenarios?

Each batch item executes independently, and [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs) applies `InferErrorCode` to individual results. The top-level envelope returns `success: false` if any item fails, but the `data` array contains per-item `code` fields, allowing scripts to identify exactly which operations succeeded and which failed with specific error codes.

### Can I rely on the error codes remaining stable across versions?

Yes. The error codes (`not_found`, `invalid_value`, etc.) are part of OfficeCLI's public contract rather than implementation details. The exhaustive mapping in [`OutputFormatter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/OutputFormatter.cs) (lines 317-596) and the final fallback to `internal_error` (lines 713-715) ensure that even new error types receive stable classifications, maintaining backward compatibility for automation scripts.