How to Handle Warnings and Errors When Performing Batch Operations with OfficeCLI

Use --stop-on-error to abort on first failure, --best-effort to keep successful items while discarding failures, or omit both for continue-on-error with full result reporting.

OfficeCLI's batch command lets you execute multiple document operations in a single JSON array, reducing round-trips and improving performance. Because multiple commands run together, the CLI provides granular control over error handling, warning suppression, and atomicity guarantees. This guide explains how to manage warnings and errors effectively based on the actual implementation in the iOfficeAI/OfficeCLI repository.

Understanding Error Policy Options in OfficeCLI Batch Operations

The batch implementation in src/officecli/CommandBuilder.Batch.cs supports three distinct error handling modes. Choosing the right mode depends on whether you need atomic guarantees, maximum throughput, or deterministic failure behavior.

Stop-on-Error Mode (--stop-on-error)

The --stop-on-error flag aborts the entire batch immediately when any command fails. This is the recommended choice for scripts that require predictable outcomes.

officecli batch presentation.pptx --input operations.json --stop-on-error

As implemented at lines 35-45 of CommandBuilder.Batch.cs, this flag overrides the default continue-on-error behavior. When triggered, the CLI exits with code 1 and reports the specific failing item.

Best-Effort Mode (--best-effort)

The --best-effort flag restores pre-atomic semantics: successfully executed items persist, while failures are logged and skipped. This mode is useful for bulk operations where some commands may target unsupported features.

officecli batch document.docx --input operations.json --best-effort

The implementation at lines 46-52 of CommandBuilder.Batch.cs disables atomic rollback when this flag is present. Note: This differs from the default behavior where any failure rolls back the entire batch.

Default Continue-on-Error Behavior

When neither flag is specified, OfficeCLI attempts all commands but includes per-item error details in the final output. This provides complete visibility without sacrificing the atomic guarantee.

Warning Types and How to Suppress or Fix Them

OfficeCLI detects several warning conditions during batch processing. Understanding these warnings helps prevent silent data loss and validation failures.

Stdin Redirection Warning

When --commands or --input is used alongside redirected stdin, the CLI prints a warning at CommandBuilder.Batch.cs lines 21-28 to prevent accidental data loss. This occurs because the CLI cannot distinguish between piped JSON and file input.

To suppress this warning, set the environment variable:

export OFFICECLI_BATCH_ALLOW_STDIN_REDIRECT=1
officecli batch doc.pptx --input ops.json < /dev/null

Only disable this warning if you intentionally want to ignore piped data.

Unknown JSON Field Errors

Before deserialization, the CLI validates each batch item against BatchItem.KnownFields (defined in src/officecli/BatchTypes.cs). At lines 98-108 of CommandBuilder.Batch.cs, unknown fields trigger an ArgumentException with a field listing:


Unknown fields in batch item[2]: {"invalidField","anotherBadField"}

This early validation prevents cryptic failures during command execution.

Null Entry Detection

Array elements that are null are caught at lines 23-28 with a descriptive message:


batch item[3] is null; all items must be valid objects

This replaces potential NullReferenceException crashes with actionable error messages.

Working with Batch Results and Per-Item Errors

Each batch operation returns structured results containing success status, output data, and error details when applicable.

CLI Output Format

Results are returned as a JSON envelope or plain text depending on the --format flag. An empty batch array still validates the target file and returns a properly wrapped response (lines 29-38).


# Empty batch validates file existence

echo '[]' | officecli batch myfile.pptx --commands -

Node SDK BatchResult Structure

When using the Node SDK, Document.batch() resolves to an array of result objects with these fields:

Field Type Description
Success boolean Whether the individual command succeeded
Output object Command-specific return data
Error string Error message if Success is false
Code number Optional error code for programmatic handling

The TypeScript definition at sdk/node/index.d.ts lines 34-37 specifies BatchOptions including force, stopOnError, and timeoutMs.

Code Examples for Error Handling Patterns

Pattern 1: Strict Validation with Early Abort

#!/bin/bash
set -e

cat > critical_ops.json <<'EOF'
[
  {"command":"set","path":"/slide[1]/title","props":{"text":"Q1 Results"}},
  {"command":"set","path":"/slide[1]/chart[1]","props":{"data":[120,340,560]}}
]
EOF

# Any failure exits immediately with non-zero status

officecli batch quarterly.pptx --input critical_ops.json --stop-on-error
echo "All operations succeeded"

Pattern 2: Bulk Import with Partial Success


# Import from legacy system where some commands may fail

officecli batch legacy.docx --input migration.json --best-effort > results.json 2>errors.log

# Post-process results to identify failures

jq '.[] | select(.Success == false)' results.json

Pattern 3: Node SDK with Comprehensive Error Handling

import { open } from '@officecli/sdk';

async function robustBatch(filePath, operations) {
  const doc = await open(filePath);
  
  try {
    const result = await doc.batch(operations, {
      stopOnError: false,      // Collect all results
      bestEffort: false,       // Maintain atomicity
      force: false             // Respect document protection
    });
    
    // Analyze per-item outcomes
    const failures = result.filter(r => !r.Success);
    
    if (failures.length > 0) {
      console.error(`${failures.length} operations failed:`);
      failures.forEach((f, i) => {
        console.error(`  [${i}] ${f.Error} (code: ${f.Code})`);
      });
      
      // Optionally retry or compensate
      return { success: false, partial: result };
    }
    
    return { success: true, data: result };
    
  } catch (e) {
    // Catches validation errors (unknown fields, null items) before execution
    console.error('Batch validation failed:', e.message);
    throw e;
  }
}

// Usage
const ops = [
  { command: 'add', parent: '/slide[2]', type: 'table', props: { rows: 3, cols: 2 } },
  { command: 'set', path: '/slide[2]/table[1]/cell[1,1]', props: { text: 'Revenue' } }
];

robustBatch('report.pptx', ops);

Pattern 4: Bypassing Document Protection

// When editing protected documents programmatically
await doc.batch(operations, { force: true });

The force option at sdk/node/index.d.ts lines 34-37 mirrors the set --force CLI behavior, bypassing protection checks for the entire batch.

Special Considerations for LaTeX and Content Warnings

At lines 90-98 of CommandBuilder.Batch.cs, the CLI aggregates unrecognized LaTeX tokens across all batch items into a single unrecognizedLatex warning. This prevents individual token warnings from overwhelming output while still surfacing content issues.

When processing mathematical content, inspect the batch result for this field:

const result = await doc.batch(latexOperations);
if (result.unrecognizedLatex?.length > 0) {
  console.warn('Unrecognized LaTeX tokens:', result.unrecognizedLatex);
}

Summary

  • Choose error policy deliberately: --stop-on-error for deterministic scripts, --best-effort for maximum compatibility, or default for full reporting with atomicity
  • Handle stdin warnings by avoiding mixed input methods or setting OFFICECLI_BATCH_ALLOW_STDIN_REDIRECT=1
  • Validate JSON structure to prevent ArgumentException from unknown fields or null items
  • Inspect BatchResult objects for per-item success status, error messages, and codes
  • Use force: true sparingly to bypass document protection when necessary
  • Monitor unrecognizedLatex when processing mathematical content in batches

Frequently Asked Questions

What happens if one command in a batch fails by default?

By default, OfficeCLI uses continue-on-error behavior: all commands are attempted, and the final output includes per-item success indicators. However, if any command fails, the entire batch is rolled back to maintain atomicity. Override this with --best-effort to keep successful changes.

How do I distinguish between validation errors and execution errors?

Validation errors (unknown JSON fields, null items) throw ArgumentException before any commands run, as implemented at lines 98-108 of CommandBuilder.Batch.cs. Execution errors occur during processing and are captured in individual BatchResult.Error fields. Wrap your SDK calls in try-catch for validation errors, and inspect result arrays for execution errors.

Can I mix --stop-on-error and --best-effort?

No, these flags are mutually exclusive. The --stop-on-error flag takes precedence for early abort behavior, while --best-effort disables atomic rollback. Using both together typically results in stop-on-error behavior with best-effort persistence semantics undefined—test your specific use case.

Does the --force flag affect error handling?

No. According to the implementation at CommandBuilder.Batch.cs lines 35-45, the --force flag only bypasses document-protection checks. It does not change whether the batch stops on errors or continues processing. Use --stop-on-error or --best-effort to control error flow.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →