iOfficeAI/OfficeCLI · error · ArgumentException

'rid' property is required for chartex (pinned relationship

Error message

'rid' property is required for chartex (pinned relationship id)

What it means

chartEx is carried verbatim with pinned source relationship IDs (mirrors the pptx SmartArt pattern). The 'rid' property pins the rId the graphicFrame slice uses in the destination drawing so it resolves without rewriting. Without it the handler cannot wire the raw graphicFrame into the drawing. It is required.

Source

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

            case "chartex":
            {
                // Extended (cx:) chart carrier for dump→batch round-trip.
                // chartEx has no semantic add vocabulary — waterfall/funnel/
                // sunburst charts are carried VERBATIM: the caller pins the
                // source rIds so the graphicFrame slice raw-set into the
                // drawing resolves without rewriting. Mirrors the pptx
                // SmartArt add-part pattern (pinned rIds + raw payload).
                // Props: rid (required), xml (base64 cx:chartSpace),
                // colors-rid/colors-xml, style-rid/style-xml (optional
                // sub-parts — Excel-authored chartEx always carries both;
                // dropping them dangles the main part's rels).
                var cxSheetName = parentPartPath.TrimStart('/');
                var cxWorksheet = FindWorksheet(cxSheetName)
                    ?? throw new ArgumentException(
                        $"Sheet not found: {cxSheetName}. chartex must be added under a sheet: add-part <file> /<SheetName> --type chartex");
                properties ??= new Dictionary<string, string>();
                var cxRid = properties.GetValueOrDefault("rid")
                    ?? throw new ArgumentException("'rid' property is required for chartex (pinned relationship id)");
                var cxXmlB64 = properties.GetValueOrDefault("xml")
                    ?? throw new ArgumentException("'xml' property is required for chartex (base64 cx:chartSpace XML)");

                var cxDrawingsPart = cxWorksheet.DrawingsPart
                    ?? cxWorksheet.AddNewPart<DrawingsPart>();
                if (cxDrawingsPart.WorksheetDrawing == null)
                {
                    cxDrawingsPart.WorksheetDrawing =
                        new DocumentFormat.OpenXml.Drawing.Spreadsheet.WorksheetDrawing();
                    cxDrawingsPart.WorksheetDrawing.Save();
                    if (GetSheet(cxWorksheet).GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Drawing>() == null)
                    {
                        var cxDrawRelId = cxWorksheet.GetIdOfPart(cxDrawingsPart);
                        GetSheet(cxWorksheet).Append(
                            new DocumentFormat.OpenXml.Spreadsheet.Drawing { Id = cxDrawRelId });
                        SaveWorksheet(cxWorksheet);
                    }
                }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Set properties["rid"] to the source graphicFrame's r:id (e.g. "rId3").
  2. Re-dump to obtain the pinned rid the emitter records.
  3. Confirm the rid matches an rId that the raw-set graphicFrame will reference.

Example fix

// before
var props = new Dictionary<string,string>{ ["xml"] = cxChartB64 };
handler.AddPart("/Sheet1", "chartex", props);
// after
props["rid"] = "rId3";
handler.AddPart("/Sheet1", "chartex", props);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(properties?.GetValueOrDefault("rid")))
    throw new InvalidOperationException("chartex requires a pinned 'rid'.");

Type guard

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

Try / catch

try { handler.AddPart(parent, "chartex", props); }
catch (ArgumentException ex) when (ex.Message.Contains("'rid' property is required for chartex"))
{ /* set props["rid"] to the graphicFrame r:id, retry */ }

Prevention

When it happens

Trigger: AddPart(..., "chartex", properties) where properties has no 'rid' key or a null value.

Common situations: Hand-authored batch missing the pinned rId; a dump→batch pipeline that did not emit rid; confusing rid with the chart's own internal rIds.

Related errors


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