{"record":{"id":"34bd74e087d65a32","repo":"iOfficeAI/OfficeCLI","slug":"rid-property-is-required-for-ole-pinned-payload","errorCode":null,"errorMessage":"'rid' property is required for ole (pinned payload relationship id)","messagePattern":"'rid' property is required for ole \\(pinned payload relationship id\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.cs","lineNumber":1276,"sourceCode":"                // Verbatim OLE carrier for dump→batch round-trip. Mirrors the\n                // pptx add-part ole contract (pinned rIds + base64 payloads)\n                // but is all-in-one: Excel's OLE anatomy spans the worksheet\n                // (<oleObjects> child + embed/icon rels), the VML drawing\n                // (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.","sourceCodeStart":1258,"sourceCodeEnd":1294,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.cs#L1258-L1294","documentation":"The 'rid' property pins the relationship ID the payload part is registered under, which is referenced by the verbatim object-xml's <oleObject r:id=...>. Because the object-xml is carried verbatim, the rId must be supplied so the embed relationship and the child element agree. Required.","triggerScenarios":"AddPart(..., \"ole\", properties) where properties has no 'rid' key or a null value.","commonSituations":"Hand-authored batch missing the pinned rId; a dump that did not emit rid; confusing the payload rid with the icon-rid.","solutions":["Set properties[\"rid\"] to the rId used inside the object-xml (e.g. \"rId4\").","Re-dump so rid and object-xml are emitted consistently.","Confirm rid appears in the object-xml's r:id attribute."],"exampleFix":"// before\nvar props = new Dictionary<string,string>{ [\"data\"] = b64, [\"object-xml\"] = objXml };\nhandler.AddPart(\"/Sheet1\", \"ole\", props);\n// after\nprops[\"rid\"] = \"rId4\";\nhandler.AddPart(\"/Sheet1\", \"ole\", props);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(properties?.GetValueOrDefault(\"rid\")))\n    throw new InvalidOperationException(\"ole requires a pinned payload 'rid'.\");","typeGuard":"static bool HasRid(Dictionary<string,string>? p) =>\n    !string.IsNullOrEmpty(p?.GetValueOrDefault(\"rid\"));","tryCatchPattern":"try { handler.AddPart(parent, \"ole\", props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"'rid' property is required for ole\"))\n{ /* set props[\"rid\"] to match object-xml's r:id, retry */ }","preventionTips":["Emit rid together with object-xml so they agree.","Confirm rid is the rId used inside the object-xml.","Re-dump to keep rid, data, and object-xml consistent."],"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"}