iOfficeAI/OfficeCLI · error · ArgumentException

add-part ole: 'data' is not valid base64

Error message

add-part ole: 'data' is not valid base64

What it means

The 'data' property was present but Convert.FromBase64String threw a FormatException — the string is not valid base64 (illegal characters, wrong length, or whitespace padding issues). The inner FormatException is swallowed and rethrown as an ArgumentException naming the field.

Source

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

                // 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(
                            "application/vnd.openxmlformats-officedocument.", StringComparison.OrdinalIgnoreCase)
                        && !oleCt.Equals(
                            "application/vnd.openxmlformats-officedocument.oleObject", StringComparison.OrdinalIgnoreCase)
                        ? "package" : "object");
                // PartTypeInfo's target extension is dot-prefixed (".docx");

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Regenerate data with Convert.ToBase64String on the raw payload bytes.
  2. Strip whitespace/newlines before passing if the source wrapped lines.
  3. Validate length is a multiple of 4 and uses the standard alphabet.
  4. If you have URL-safe base64, translate -_ to +/ and add padding.

Example fix

// before — pasted, line-wrapped blob fails to decode
props["data"] = wrappedPastedBlob;
// after — regenerate cleanly from the raw bytes
props["data"] = Convert.ToBase64String(
    File.ReadAllBytes("/unpack/xl/embeddings/oleObject1.bin"));
Defensive patterns

Strategy: try-catch

Validate before calling

try { Convert.FromBase64String(props["data"]); }
catch (FormatException) { /* strip whitespace, regenerate, or translate URL-safe base64 */ }

Type guard

static bool IsValidBase64(string? s)
{ if (string.IsNullOrEmpty(s) || s.Length % 4 != 0) return false;
 try { Convert.FromBase64String(s); return true; } catch { return false; } }

Try / catch

try { handler.AddPart(parent, "ole", props); }
catch (ArgumentException ex) when (ex.Message.Contains("'data' is not valid base64"))
{ /* regenerate with Convert.ToBase64String, retry */ }

Prevention

When it happens

Trigger: data contains characters outside the base64 alphabet, has an invalid length (not a multiple of 4 after padding), embedded whitespace/newlines that some encoders reject, or was double-encoded.

Common situations: Manually pasting a base64 blob that got line-wrapped or truncated; a UTF-8 string mistaken for base64; base64 with URL-safe chars (-/_) instead of standard (+//); missing padding '='.

Related errors


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