{"record":{"id":"e7560896c15e86c0","repo":"iOfficeAI/OfficeCLI","slug":"object-xml-property-is-required-for-ole-verbati","errorCode":null,"errorMessage":"'object-xml' property is required for ole (verbatim oleObjects child element)","messagePattern":"'object-xml' property is required for ole \\(verbatim oleObjects child element\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.cs","lineNumber":1280,"sourceCode":"                // (anchor shape) and <legacyDrawing>, all of which must stay\n                // consistent — so the handler wires everything here instead\n                // of leaving XML splicing to a companion raw-set.\n                // Props: rid + data (+content-type/extension) = payload part;\n                // icon-rid + icon-data (+icon-content-type) = objectPr image;\n                // vml-shape = the <v:shape> anchor XML verbatim;\n                // object-xml = the <oleObjects> CHILD element verbatim\n                // (mc:AlternateContent or bare oleObject, pinned rIds inside).\n                var oleSheetName = parentPartPath.TrimStart('/');\n                var oleWs = FindWorksheet(oleSheetName)\n                    ?? throw new ArgumentException(\n                        $\"Sheet not found: {oleSheetName}. ole must be added under a sheet: add-part <file> /<SheetName> --type ole\");\n                properties ??= new Dictionary<string, string>();\n                var oleRid = properties.GetValueOrDefault(\"rid\")\n                    ?? throw new ArgumentException(\"'rid' property is required for ole (pinned payload relationship id)\");\n                var oleDataB64 = properties.GetValueOrDefault(\"data\")\n                    ?? throw new ArgumentException(\"'data' property is required for ole (base64 payload bytes)\");\n                var oleObjectXml = properties.GetValueOrDefault(\"object-xml\")\n                    ?? throw new ArgumentException(\"'object-xml' property is required for ole (verbatim oleObjects child element)\");\n                byte[] oleBytes;\n                try { oleBytes = Convert.FromBase64String(oleDataB64); }\n                catch (FormatException) { throw new ArgumentException(\"add-part ole: 'data' is not valid base64\"); }\n\n                var oleCt = properties.GetValueOrDefault(\"content-type\")\n                    ?? \"application/vnd.openxmlformats-officedocument.oleObject\";\n                var oleExt = properties.GetValueOrDefault(\"extension\") ?? \".bin\";\n                if (!oleExt.StartsWith('.')) oleExt = \".\" + oleExt;\n\n                // Kind comes from the dump (source part type), because content\n                // type alone cannot classify legacy package formats (.xls\n                // carries application/vnd.ms-excel, not an OOXML CT). Fallback\n                // for hand-written batches that omit ole-kind: package iff the\n                // CT is a non-oleObject openxmlformats CT.\n                var oleKind = properties.GetValueOrDefault(\"ole-kind\")\n                    ?? (oleCt.StartsWith(\n                            \"application/vnd.openxmlformats-officedocument.\", StringComparison.OrdinalIgnoreCase)\n                        && !oleCt.Equals(","sourceCodeStart":1262,"sourceCodeEnd":1298,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.cs#L1262-L1298","documentation":"The 'object-xml' property carries the verbatim <oleObjects> child element (an <mc:AlternateContent> or bare <oleObject>) with its pinned rIds. It is required because the handler appends it directly into the worksheet's <oleObjects>; there is no semantic OLE construction path.","triggerScenarios":"AddPart(..., \"ole\", properties) where properties has no 'object-xml' key or a null value.","commonSituations":"Hand-authored batch missing the child element; a dump that emitted only the payload and icon but not the oleObjects element; supplying the whole <worksheet> root instead of just the child.","solutions":["Set properties[\"object-xml\"] to the verbatim <oleObject> (or <mc:AlternateContent>) markup.","Ensure the r:id inside matches the supplied 'rid'.","Re-dump to capture the exact child element."],"exampleFix":"// before\nvar props = new Dictionary<string,string>{ [\"rid\"]=\"rId4\", [\"data\"] = b64 };\nhandler.AddPart(\"/Sheet1\", \"ole\", props);\n// after\nprops[\"object-xml\"] = \"<oleObject r:id=\\\"rId4\\\" ... />\";\nhandler.AddPart(\"/Sheet1\", \"ole\", props);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(properties?.GetValueOrDefault(\"object-xml\")))\n    throw new InvalidOperationException(\"ole requires verbatim 'object-xml'.\");","typeGuard":"static bool HasObjectXml(Dictionary<string,string>? p) =>\n    !string.IsNullOrEmpty(p?.GetValueOrDefault(\"object-xml\"));","tryCatchPattern":"try { handler.AddPart(parent, \"ole\", props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"'object-xml' property is required for ole\"))\n{ /* supply the oleObjects child element, retry */ }","preventionTips":["Supply the <oleObject>/<mc:AlternateContent> child, not the whole worksheet.","Ensure the r:id inside matches the supplied rid.","Re-dump to capture the exact child element."],"tags":["excel","openxml","add-part","ole","required-property"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}