iOfficeAI/OfficeCLI · error · ArgumentException

'data' property is required for ole (base64 payload bytes)

Error message

'data' property is required for ole (base64 payload bytes)

What it means

The 'data' property holds the base64-encoded OLE payload bytes (the .bin content of the embedded object). It is required because the handler writes these bytes into the new embedded object part. Without it there is no payload to store.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.cs:1278

                // but is all-in-one: Excel's OLE anatomy spans the worksheet
                // (<oleObjects> child + embed/icon rels), the VML drawing
                // (anchor shape) and <legacyDrawing>, all of which must stay
                // consistent — so the handler wires everything here instead
                // of leaving XML splicing to a companion raw-set.
                // Props: rid + data (+content-type/extension) = payload part;
                // icon-rid + icon-data (+icon-content-type) = objectPr image;
                // vml-shape = the <v:shape> anchor XML verbatim;
                // object-xml = the <oleObjects> CHILD element verbatim
                // (mc:AlternateContent or bare oleObject, pinned rIds inside).
                var oleSheetName = parentPartPath.TrimStart('/');
                var oleWs = FindWorksheet(oleSheetName)
                    ?? throw new ArgumentException(
                        $"Sheet not found: {oleSheetName}. ole must be added under a sheet: add-part <file> /<SheetName> --type ole");
                properties ??= new Dictionary<string, string>();
                var oleRid = properties.GetValueOrDefault("rid")
                    ?? throw new ArgumentException("'rid' property is required for ole (pinned payload relationship id)");
                var oleDataB64 = properties.GetValueOrDefault("data")
                    ?? throw new ArgumentException("'data' property is required for ole (base64 payload bytes)");
                var oleObjectXml = properties.GetValueOrDefault("object-xml")
                    ?? throw new ArgumentException("'object-xml' property is required for ole (verbatim oleObjects child element)");
                byte[] oleBytes;
                try { oleBytes = Convert.FromBase64String(oleDataB64); }
                catch (FormatException) { throw new ArgumentException("add-part ole: 'data' is not valid base64"); }

                var oleCt = properties.GetValueOrDefault("content-type")
                    ?? "application/vnd.openxmlformats-officedocument.oleObject";
                var oleExt = properties.GetValueOrDefault("extension") ?? ".bin";
                if (!oleExt.StartsWith('.')) oleExt = "." + oleExt;

                // Kind comes from the dump (source part type), because content
                // type alone cannot classify legacy package formats (.xls
                // carries application/vnd.ms-excel, not an OOXML CT). Fallback
                // for hand-written batches that omit ole-kind: package iff the
                // CT is a non-oleObject openxmlformats CT.
                var oleKind = properties.GetValueOrDefault("ole-kind")
                    ?? (oleCt.StartsWith(

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Set properties["data"] = Convert.ToBase64String(File.ReadAllBytes(...)) for the .bin payload.
  2. Re-dump so the base64 payload is captured from the source embeddings part.
  3. For linked OLE objects (no embedded payload), this carrier is the wrong tool.

Example fix

// before
var props = new Dictionary<string,string>{ ["rid"]="rId4", ["object-xml"]=objXml };
handler.AddPart("/Sheet1", "ole", props);
// after
props["data"] = Convert.ToBase64String(
    File.ReadAllBytes("/unpack/xl/embeddings/oleObject1.bin"));
handler.AddPart("/Sheet1", "ole", props);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(properties?.GetValueOrDefault("data")))
    throw new InvalidOperationException("ole requires base64 'data' payload.");

Type guard

static bool HasData(Dictionary<string,string>? p) =>
    !string.IsNullOrEmpty(p?.GetValueOrDefault("data"));

Try / catch

try { handler.AddPart(parent, "ole", props); }
catch (ArgumentException ex) when (ex.Message.Contains("'data' property is required for ole"))
{ /* encode the .bin bytes, retry */ }

Prevention

When it happens

Trigger: AddPart(..., "ole", properties) where properties has no 'data' key or its value is null/empty.

Common situations: Hand-authored batch omitting the payload; a serialization layer stripping the large base64; targeting an OLE link (no payload) instead of an embedded object.

Related errors


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