# How OfficeCLI Batch Mode Handles Atomic Operations with Rollback on Failure

> OfficeCLI batch mode ensures atomic operations with automatic rollback on failure. Discover how it maintains document integrity using disk barriers and in-memory mutations.

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

---

**OfficeCLI guarantees atomic batch execution by combining a pre-batch disk barrier, deferred in-memory mutations, and automatic file reloading to restore the original document state if any operation fails.**

OfficeCLI, the open-source document automation CLI from the iOfficeAI/OfficeCLI repository, provides a sophisticated batch processing system that treats multi-step document mutations as atomic transactions. When executing commands like `set`, `add`, `remove`, `move`, or `swap` against Word documents, the tool ensures that either every operation succeeds or the document reverts to its pre-batch state without partial modifications. This article examines the three-phase mechanism implemented in [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) that enables true all-or-nothing semantics.

## The Three-Phase Atomicity Architecture

### Phase 1: Pre-Batch Flush Barrier

Before executing the first mutation, the resident server writes the current in-memory DOM to disk to create a deterministic rollback point. This barrier, implemented in [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) (lines 1241-1248), ensures the on-disk file reflects the exact pre-batch state before any modifications occur. By flushing the document to storage upfront, OfficeCLI establishes a pristine snapshot that can be reloaded if subsequent operations encounter errors.

### Phase 2: Deferred Saves During Execution

During batch processing, the system temporarily disables automatic document serialization by setting the handler's `DeferSave` flag to `true`. As defined in [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) (lines 71-78), this deferral mechanism prevents intermediate states from reaching the disk and eliminates the O(N²) performance cost of saving after every individual mutation. Each command modifies only the resident in-memory DOM, leaving the disk snapshot untouched until the batch completes successfully.

### Phase 3: Atomic Rollback on Failure

After processing all batch items, the server checks the `anyFailed` condition to determine if any mutation encountered an error. If the batch was configured as atomic (the default) and a failure occurred, the system disposes the resident handler, discards the modified in-memory DOM, and reloads the original file from the pre-batch snapshot. This rollback logic in [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) (lines 1212-1239) effectively restores the document to its exact pre-execution state, ensuring zero side effects from failed operations.

## Implementation Details and Handler Coordination

The atomic guarantee relies on tight coordination between [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) and document-specific handlers such as [`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs). The handler's `DeferSave` property controls the autosave watchdog, while `SnapshotPendingWholeParts` and `DiscardOnDispose` hooks enable clean teardown during rollback scenarios. [`CommandBuilder.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.cs) parses the JSON batch payload, executes each mutation, and tracks success states to trigger the rollback mechanism when necessary.

## Practical Usage and Edge Cases

Atomic mode is the default behavior for all batch operations. To execute a batch with atomic guarantees:

```bash
officecli batch --file report.docx \
  '[{"command":"set","path":"/body/p[1]","prop":"bold","value":true},
    {"command":"add","path":"/body","type":"image","src":"logo.png"}]'

```

To disable atomicity and continue processing after individual failures, use the `--best-effort` flag:

```bash
officecli batch --best-effort --file report.docx \
  '[{"command":"set","path":"/body/p[1]","prop":"bold","value":true},
    {"command":"set","path":"/nonexistent","prop":"color","value":"red"}]'

```

Critical edge cases and guarantees include:

- **Read-only batches**: When commands contain only `get`, `query`, or `view` verbs, the atomic barrier is skipped entirely since no mutations occur.
- **Resident flush mode OFF**: If the resident handler's flush mode is disabled, the pre-batch barrier throws a `CliException` because no on-disk rollback point exists. You must either save the document manually before batching or use `--best-effort`.
- **Partial failures**: In atomic mode, any single failure triggers complete rollback, returning exit code 1 and leaving the original document unchanged via `CommandBuilder.PrintBatchResults`.

## Summary

- OfficeCLI batch mode implements **atomic operations** through a pre-batch flush barrier that snapshots document state to disk before any mutations occur.
- **Deferred saves** prevent intermediate states from persisting during batch execution, keeping the disk snapshot pristine while modifying only the in-memory DOM.
- On failure, the system **reloads the original file** from the pre-batch snapshot, discarding the modified resident handler to ensure all-or-nothing semantics.
- The `--best-effort` flag disables atomicity, allowing partial success but removing rollback guarantees.
- Implementation spans [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs), [`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs) (via `DeferSave` and `DiscardOnDispose`), and [`CommandBuilder.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.cs) with specific line references to the barrier, deferral, and rollback logic.

## Frequently Asked Questions

### What happens if a batch command fails in the middle of execution?

If any mutation fails during an atomic batch, OfficeCLI immediately stops processing subsequent commands, disposes the resident handler containing the modified DOM, and reloads the document from the pre-batch disk snapshot created by the flush barrier. This ensures the file reverts to its exact pre-execution state, with the failure reported through a non-zero exit code and `CommandBuilder.PrintBatchResults`.

### How does the pre-batch barrier affect performance?

The barrier imposes a single upfront save operation before mutations begin. While this adds initial latency, it prevents the O(N²) cost of saving after every mutation and eliminates the risk of partial writes. The rollback cost is limited to a single file reload, making the atomic guarantee efficient even for large batches.

### Can I use atomic batch mode with the resident server's flush mode disabled?

No. If the resident handler's flush mode is set to `OFF`, the pre-batch barrier cannot create a disk snapshot, causing OfficeCLI to throw a `CliException`. You must either save the document manually before batching or use the `--best-effort` flag to disable atomic requirements.

### What is the difference between atomic mode and best-effort mode?

Atomic mode (default) guarantees that all mutations succeed or none are applied, using rollback mechanisms to restore the original document on failure. Best-effort mode (`--best-effort`) processes each command independently, reporting failures without stopping execution or rolling back previous successful mutations, which may leave the document in a partially modified state.