# How to Validate Office Document Integrity with OfficeCLI: A Complete Guide

> Learn to validate Office document integrity using OfficeCLI. This guide details how OfficeCLI uses a resident server and handlers to ensure document accuracy and returns structured results.

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

---

**The OfficeCLI validates Office document integrity by running a resident server that executes type-specific handlers and returns structured results with machine-readable exit codes.**

The `iOfficeAI/OfficeCLI` repository provides a cross-platform command-line tool for inspecting, editing, and validating Microsoft Office documents. This guide explains exactly how the validation pipeline works, where to find key implementation details, and how to integrate document integrity checks into your automation workflows.

## Understanding the OfficeCLI Validation Architecture

OfficeCLI uses a **resident server model** to process validation requests. When you invoke the `validate` command, the CLI launches a persistent server process that deserializes JSON requests, routes them to the appropriate document handler, and returns standardized responses.

The validation flow spans three architectural layers:

- **Request processing** ([`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs)) — parses commands and manages state
- **Handler delegation** ([`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs), etc.) — routes to type-specific validators
- **XML validation** (`RawXmlHelper`) — executes OpenXML SDK schema checks

## Step-by-Step Validation Execution

### Receiving and Routing the Validate Command

In [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs), incoming requests are inspected for the `validate` command. The server maintains a `_lastValidateErrorCount` field to track validation state across requests:

```csharp
// ResidentServer.cs – lines 828-831
var isValidate = request.Command.Equals("validate", StringComparison.OrdinalIgnoreCase);
var validateFailure = isValidate && _lastValidateErrorCount > 0;
if (isValidate) _lastValidateErrorCount = 0;

```

This pattern allows the server to reset error state for fresh validations while preserving failure information for exit-code determination.

### Executing Document-Specific Validation

The `ExecuteValidate` method (lines 331-348) orchestrates the actual validation:

```csharp
// ResidentServer.cs – lines 331-348
private void ExecuteValidate()
{
    var errors = _handler.Validate();
    _lastValidateErrorCount = errors.Count;
    if (errors.Count == 0)
        Console.WriteLine("Validation passed: no errors found.");
    else
        foreach (var err in errors) Console.Error.WriteLine($"  [{err.ErrorType}] {err.Description}");
}

```

Key implementation details:

- Validation errors are written to **stderr**, not stdout
- Each error includes `ErrorType` and `Description` from the `ValidationError` object
- The error count is stored for later exit-code calculation

### Handler Implementation: Word Documents

Document handlers expose a uniform `Validate()` interface. For Word documents in [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs), the implementation delegates to a shared XML helper:

```csharp
// WordHandler.cs – line 2263
public List<ValidationError> Validate() => RawXmlHelper.ValidateDocument(_doc, _filePath);

```

The `RawXmlHelper.ValidateDocument` method invokes the OpenXML SDK validator, which performs strict OOXML schema validation against the document's package parts.

## Exit-Code Semantics for Automation

OfficeCLI implements a **three-state exit code system** that enables reliable shell scripting:

| Condition | Exit Code | Detection Mechanism |
|-----------|-----------|---------------------|
| Validation errors detected | **1** | `validateFailure` flag (non-zero `_lastValidateErrorCount`) |
| Unsupported property/operation | **2** | `stderr.Contains("UNSUPPORTED")` |
| Success | **0** | Default path |

In JSON mode, this logic appears in lines 779-786:

```csharp
// ResidentServer.cs – lines 779-786
int jsonExitCode = 0;
if (batchFailure || validateFailure)               jsonExitCode = 1;
else if (stderr.Contains("UNSUPPORTED") …)        jsonExitCode = 2;
else if (!EnvelopeSuccess(envelope) …)            jsonExitCode = 1;
return MakeResponse(jsonExitCode, envelope, "");

```

Text mode uses equivalent logic (lines 894-897) with the same threshold conditions.

## Practical Usage Examples

### Command-Line Validation with Stderr Capture

Validate a Word document and capture errors for logging:

```bash

# Validate and capture exit code

$ officecli validate report.docx 2>validation_errors.log
VALIDATION: 3 validation error(s) found:
  [InvalidValue] The attribute "w:val" on element "w:shd" is invalid.
  [MissingRequired] Element "w:tblPr" is required but missing.
  [InvalidChild] Unexpected child element "w:footnoteReference".

# Check result in shell scripts

if [ $? -ne 0 ]; then
    echo "Document failed validation, see errors above"
    exit 1
fi

```

### JSON Mode for API Integration

Machine-readable output for CI/CD pipelines:

```bash
$ officecli --json validate presentation.pptx
{
  "success": false,
  "data": null,
  "warnings": [
    "VALIDATION: 2 validation error(s) found"
  ]
}

```

The `--json` flag ensures output is parseable, while the exit code (1) signals failure without requiring JSON parsing.

### Programmatic Validation via the SDK

For .NET applications, validate documents without spawning CLI processes:

```csharp
using OfficeCli;

// Load document through factory
var handler = DocumentHandlerFactory.Open("budget.xlsx");

// Execute validation directly
var errors = handler.Validate();   // Returns List<ValidationError>

foreach (var error in errors)
{
    Console.WriteLine($"{error.ErrorType} at {error.Path}: {error.Description}");
}

// Clean documents return empty list
if (errors.Count == 0)
    Console.WriteLine("Document integrity verified");

```

## Validation Error Object Structure

Each `ValidationError` exposed by `handler.Validate()` contains:

- **ErrorType**: Classification (e.g., `InvalidValue`, `MissingRequired`, `InvalidChild`)
- **Description**: Human-readable explanation
- **Path**: XPath or package part location
- **Part**: Specific OpenXML package part (e.g., [`document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/document.xml), [`styles.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/styles.xml))

These fields map directly to OpenXML SDK validation event arguments, providing precise diagnostic information for document repair workflows.

## Key Source Files for Validation

| File | Purpose | Critical Lines |
|------|---------|--------------|
| [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) | Request routing, exit code logic, stderr formatting | 331-348 (ExecuteValidate), 779-786 (JSON exit codes), 828-831 (command detection), 894-897 (text exit codes) |
| [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs) | Word-specific validation entry point | 2263 (Validate method) |
| [`src/officecli/Handlers/Word/RawXmlHelper.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Word/RawXmlHelper.cs) | OpenXML SDK validator invocation | `ValidateDocument` static method |

## Summary

- **OfficeCLI validate command** runs through a resident server that deserializes JSON requests and routes to document-type handlers
- **Exit code 1** indicates validation errors; **exit code 2** indicates unsupported operations; **exit code 0** indicates success
- **Validation errors** are written to stderr with structured prefixes, enabling both human review and programmatic parsing
- **Word documents** validate via `WordHandler.Validate()` → `RawXmlHelper.ValidateDocument()` → OpenXML SDK schema validation
- **JSON mode** (`--json`) provides structured responses while preserving the same exit code semantics as text mode

## Frequently Asked Questions

### How does OfficeCLI determine if a document failed validation?

OfficeCLI sets `validateFailure = true` when `_lastValidateErrorCount > 0` after executing `ExecuteValidate()`. This flag forces exit code 1 in both JSON and text output modes. The error count is populated by `handler.Validate()`, which returns a `List<ValidationError>` from the OpenXML SDK validator.

### Can I validate Excel or PowerPoint files, or is validation limited to Word documents?

The `Validate()` method is defined on the base `IDocumentHandler` interface, and each handler implements type-specific validation. While the source analysis highlights [`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs) at line 2263, Excel and PowerPoint handlers implement equivalent `Validate()` methods that delegate to `RawXmlHelper.ValidateDocument()` with their respective document types.

### Why does OfficeCLI write validation errors to stderr instead of stdout?

Writing to stderr ensures that structured output modes (like `--json`) remain valid and parseable even when validation fails. Stderr output also allows shell scripts to separate diagnostic information from primary output streams using standard redirection (`2>`). The `VALIDATION:` prefix further enables grep-based filtering without JSON parsing.

### How can I integrate OfficeCLI validation into a CI/CD pipeline?

Use the exit code contract: `officecli validate document.docx || exit 1` fails builds automatically. For detailed reporting, capture stderr to artifacts: `officecli validate document.docx 2>validation-report.txt`. For machine-readable artifacts, use `--json` and parse the `success` field, while still relying on exit codes for pipeline control flow.