iOfficeAI/OfficeCLI · error · CliException

corrupt_file

corrupt_file

Error message

Cannot open {Path.GetFileName(filePath)}: file is 0 bytes (not a valid Office document).

What it means

Thrown by DocumentHandlerFactory.Open when the file exists but has a length of 0 bytes. A 0-byte file is not a valid OOXML package, but the Open XML SDK 3.x silently materializes an empty Package in read-write mode, returning a handler with a fake root node and no parts — causing subsequent commands to report fake success on an unusable document. This guard rejects the file up-front with the same corrupt_file UX that read-only mode already produced.

Source

Thrown at src/officecli/Handlers/DocumentHandlerFactory.cs:48

            };

        if (!File.Exists(filePath))
            throw new CliException($"File not found: {filePath}")
            {
                Code = "file_not_found",
                Suggestion = "Check the file path. Use an absolute path or a path relative to the current directory.",
                Help = "officecli create <path> --type docx|xlsx|pptx"
            };

        // CONSISTENCY(corrupt-file-rejection): a 0-byte file is silently
        // accepted by Open XML SDK 3.x in read-write mode (it materialises an
        // empty Package), but the resulting handler returns a fake root node
        // with no parts. CLI commands that follow then report success and
        // exit 0 even though the document is unusable. Reject the file
        // up-front so the same file_not_found / corrupt_file UX applies that
        // direct-mode (read-only) Open already gave for 0-byte files.
        if (new FileInfo(filePath).Length == 0)
            throw new CliException($"Cannot open {Path.GetFileName(filePath)}: file is 0 bytes (not a valid Office document).")
            {
                Code = "corrupt_file",
                Suggestion = "Recreate the file with: officecli create <path>"
            };

        var ext = Path.GetExtension(filePath).ToLowerInvariant();

        // CONSISTENCY(dos-hardening): reject decompression bombs before the
        // Open XML SDK / System.IO.Packaging touches the package. A few KB of
        // zip can inflate to many gigabytes and OOM the process (or, on a
        // 32-bit size-field overflow, surface only as a raw "Arithmetic
        // operation resulted in an overflow"). Only the native zip formats are
        // inspected; plugin-handled formats may not be zips and are left to
        // their own handler. See DocumentLimits for the thresholds.
        if (IsNativeOoxml(ext))
            GuardDecompressionBomb(filePath);

        // CONSISTENCY(dangling-rel-repair): the reactive catch below only fires

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Recreate the file: 'officecli create <path> --type docx|xlsx|pptx' to generate a valid blank document.
  2. Re-download or re-copy the source file and verify it is non-zero size before opening.
  3. Check the file size in your script before passing it to the CLI: if (new FileInfo(path).Length == 0) { /* handle */ }.
Defensive patterns

Strategy: validation

Validate before calling

// Check file size before opening
var info = new FileInfo(filePath);
if (info.Length == 0)
    throw new InvalidOperationException($"File is empty (0 bytes): {filePath}");
var handler = DocumentHandlerFactory.Open(filePath);

Type guard

static bool IsNonEmptyFile(string path) => File.Exists(path) && new FileInfo(path).Length > 0;

Try / catch

try
{
    var handler = DocumentHandlerFactory.Open(filePath);
}
catch (CliException ex) when (ex.Code == "corrupt_file" && ex.Message.Contains("0 bytes"))
{
    // The file is empty — recreate or re-download
    logger.LogWarning("File {Path} is 0 bytes. Recreating.", filePath);
    // officecli create <path> --type docx
    throw;
}

Prevention

When it happens

Trigger: The file path points to a real file that is exactly 0 bytes long. This happens when a download was interrupted before any data was written, a 'touch' command created an empty file, a git checkout left an empty placeholder, or a previous failed write left a truncated file.

Common situations: A CI pipeline downloading a template document from an artifact store where the download failed silently; a user who ran 'touch report.docx' intending to create it later; a partially synced cloud-storage file; a previous officecli run that crashed during create before writing any zip content.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/b930ce944cb95477. Report an issue: GitHub.