# How OfficeCLI CommandBuilder.Batch Handles Bulk Operations Across Documents

> Discover how OfficeCLI CommandBuilder.Batch streamlines bulk operations across documents performing optimized single-pass execution in local or server modes with deferred I/O and error aggregation.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: internals
- Published: 2026-07-08

---

**OfficeCLI's `CommandBuilder.Batch` executes multiple document commands in a single optimized pass, supporting both resident server and local execution modes with deferred I/O and comprehensive error aggregation.**

The `CommandBuilder.Batch` implementation in the [iOfficeAI/OfficeCLI](https://github.com/iOfficeAI/OfficeCLI) repository provides the central engine for automating complex document manipulations across Word, PowerPoint, and Excel files. This component processes JSON-defined operation sequences, validates schemas against strict definitions, and coordinates execution across hundreds of items while minimizing disk access and memory overhead.

## Architecture of the Batch Command Engine

The batch system operates through three distinct layers that transform user input into efficient document mutations.

### Command Definition and Input Parsing

The entry point `BuildBatchCommand` in [`src/officecli/CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Batch.cs) (lines 18-45) constructs the `batch` sub-command and handles three mutually exclusive input sources: file paths via `--input`, inline JSON via `--commands`, or stdin streams. The parser performs BOM stripping and envelope unwrapping to ensure clean JSON deserialization before reaching the validation layer.

Input validation occurs in the loop starting at line 14 (extending through line 64), which verifies that each batch item conforms to the expected schema before execution begins. This early validation prevents partial document corruption by rejecting malformed payloads before any mutations occur.

### The Batch Replay Loop

The `ApplyBatchItems` method (lines 50-78 in [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs)) serves as the core execution engine. This loop iterates over deserialized `BatchItem` instances, invoking `ExecuteBatchItem` for each operation while collecting results and LaTeX warning tokens. The implementation automatically skips resident-only commands such as `open` and `close`, wrapping each item in individual try-catch blocks to isolate failures and prevent cascade errors.

## Execution Paths: Resident vs Non-Resident

`CommandBuilder.Batch` dynamically selects between two execution strategies based on server availability, optimizing for either latency or throughput.

### Resident Server Mode

When a resident process is detected, the batch system builds a single `ResidentRequest` containing the entire JSON payload and transmits it via `ResidentClient.TrySend`. This approach eliminates per-operation document opening overhead by keeping the target file loaded in memory throughout the batch execution, making it ideal for high-frequency automation scenarios.

### Local Execution with Deferred Saves

In non-resident mode, the handler opens the document once, sets `DeferSave = true` to prevent intermediate disk writes, runs the replay loop, and flushes changes exactly once during disposal. This deferred save mechanism significantly reduces I/O bottlenecks when processing hundreds of modifications to large documents.

Protection checks via `GetBatchProtectionBlock` execute once for the entire batch unless the `--force` flag is specified, ensuring consistent security validation without redundant prompts for each operation.

## Batch Item Format and Schema

Each JSON object in a batch array must contain a `command` field (the operation verb) and optional sibling fields defined in [`src/officecli/BatchTypes.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/BatchTypes.cs) (lines 66-71). Valid properties include `path`, `parent`, `type`, `props`, and `to`, depending on the specific command requirements.

The schema enforces type safety through JSON converters declared in [`BatchTypes.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BatchTypes.cs), ensuring that property values match expected formats before reaching the execution layer. This strict typing prevents runtime errors during document manipulation.

## Error Handling and Exit Codes

The batch processor implements granular failure management through the `--stop-on-error` flag. When enabled, execution aborts immediately upon the first failure; otherwise, the loop continues and aggregates per-item errors in the result array.

Exit codes follow a strict hierarchy:
- **0** indicates complete success
- **1** signals that at least one batch item failed
- **2** indicates only unrecognized LaTeX warnings were encountered (mirroring single-command behavior)

All output wraps in a consistent JSON envelope (`{ "success": ..., "data": ... }`) ensuring identical response structures for both resident and non-resident paths, simplifying downstream automation logic.

## Practical Usage Examples

Execute inline JSON commands directly:

```bash
officecli batch mydoc.docx \
  --commands '[{"command":"add","parent":"/slide[1]","type":"shape","props":{"text":"Hi"}}]' \
  --json

```

Process operations from a file:

```bash
cat > ops.json <<'EOF'
[
  {"command":"add","parent":"/slide[1]","type":"shape","props":{"text":"Hi","x":"1cm","y":"2cm"}},
  {"command":"set","path":"/slide[1]/shape[1]","props":{"bold":"true"}},
  {"command":"remove","path":"/slide[2]/shape[3]"}
]
EOF
officecli batch mydoc.pptx --input ops.json

```

Pipe JSON via stdin:

```bash
cat ops.json | officecli batch mydoc.docx

```

Enable abort-on-failure mode:

```bash
officecli batch mydoc.docx --input ops.json --stop-on-error

```

Bypass document protection checks:

```bash
officecli batch mydoc.docx --input ops.json --force

```

## Summary

- **Three-layer architecture**: Input parsing (`BuildBatchCommand`), validation (lines 14-64), and execution (`ApplyBatchItems`) create a robust pipeline in [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs).
- **Dual execution modes**: Resident server mode uses `ResidentClient.TrySend` for single-request processing, while non-resident mode leverages `DeferSave` to minimize disk I/O.
- **Strict schema validation**: Batch items require a `command` field and optional properties defined in [`BatchTypes.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BatchTypes.cs) (lines 66-71).
- **Flexible error handling**: `--stop-on-error` provides immediate failure detection, while aggregated reporting supports exit codes 1 (failure) and 2 (LaTeX warnings only).
- **Consistent output**: JSON envelopes ensure uniform responses across all execution paths.

## Frequently Asked Questions

### What is the difference between resident and non-resident batch execution?

Resident execution sends the entire batch as a single JSON payload to a running server process via `ResidentClient.TrySend`, keeping documents open in memory for maximum throughput. Non-resident execution opens the document locally, enables `DeferSave` to buffer changes, and writes to disk exactly once when the handler disposes, optimizing for stand-alone automation scripts.

### How does OfficeCLI handle errors during batch operations?

By default, `CommandBuilder.Batch` continues processing after individual item failures and returns exit code 1 if any operation fails. When `--stop-on-error` is specified, the loop terminates immediately on the first exception. Warnings about unrecognized LaTeX tokens result in exit code 2, maintaining parity with single-command behavior.

### What fields are required in a batch item JSON object?

Every batch item must include a `command` field containing the operation verb. According to [`BatchTypes.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BatchTypes.cs) (lines 66-71), optional fields include `path`, `parent`, `type`, `props`, and `to`, with specific requirements varying by command type. The validation loop in [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs) ensures all provided fields match the expected schema before execution.

### How can I optimize batch performance for large document sets?

Use resident mode when available to eliminate per-operation document opening overhead. For non-resident execution, the built-in `DeferSave` mechanism automatically optimizes disk I/O by flushing changes only once after the entire batch completes. Additionally, avoid `--stop-on-error` unless necessary, as continuing past recoverable errors maximizes throughput for large operation sets.