iOfficeAI/OfficeCLI · error · ArgumentException

OLE object {oleIdx} not found at /{sheetNameFromPath} (avail

Error message

OLE object {oleIdx} not found at /{sheetNameFromPath} (available: {oleList.Count}).

What it means

Thrown for /Sheet/ole[N] (aliases: oleobject / object / embed) when N is outside the 1-based range [1, CollectOleNodesForSheet(...).Count]. OLE/embedded objects are gathered from the sheet's drawings/control deform; the message reports how many are available.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Query.cs:785

        if (slicerMatch.Success)
        {
            var slIdx = int.Parse(slicerMatch.Groups[1].Value);
            if (!TryFindSlicerByIndex(worksheet, slIdx, out var slicerElem, out var slicerCache) || slicerElem == null)
                throw new ArgumentException($"slicer[{slIdx}] not found on sheet '{sheetNameFromPath}'");
            var slNode = new DocumentNode { Path = path, Type = "slicer" };
            ReadSlicerProperties(slicerElem, slicerCache, slNode);
            return slNode;
        }

        // OLE object path: /Sheet1/ole[N]
        // CONSISTENCY(ole-alias): "oleobject" mirrors Add's case switch
        var oleMatch = Regex.Match(cellRef, @"^(?:ole|oleobject|object|embed)\[(\d+)\]$", RegexOptions.IgnoreCase);
        if (oleMatch.Success)
        {
            var oleIdx = int.Parse(oleMatch.Groups[1].Value);
            var oleList = CollectOleNodesForSheet(sheetNameFromPath, worksheet);
            if (oleIdx < 1 || oleIdx > oleList.Count)
                throw new ArgumentException($"OLE object {oleIdx} not found at /{sheetNameFromPath} (available: {oleList.Count}).");
            return oleList[oleIdx - 1];
        }

        // Comment path: /Sheet1/comment[N]
        var commentMatch = Regex.Match(cellRef, @"^comment\[(\d+)\]$", RegexOptions.IgnoreCase);
        if (commentMatch.Success)
        {
            var cmtIndex = int.Parse(commentMatch.Groups[1].Value);
            var commentsPart = worksheet.WorksheetCommentsPart;
            if (commentsPart?.Comments == null)
                return new DocumentNode { Path = path, Type = "error", Text = $"comment[{cmtIndex}] not found (sheet has no comments)" };

            var cmtList = commentsPart.Comments.GetFirstChild<CommentList>();
            var cmtElement = cmtList?.Elements<Comment>().ElementAtOrDefault(cmtIndex - 1);
            if (cmtElement == null)
                return new DocumentNode { Path = path, Type = "error", Text = $"comment[{cmtIndex}] not found" };

            return CommentToNode(sheetNameFromPath, cmtElement, commentsPart.Comments, cmtIndex);

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use a 1-based index in [1, oleCount].
  2. Verify the sheet has embedded objects before indexing.
  3. try/catch(ArgumentException) and read the available count from the message.

Example fix

// before
var ole = handler.Get("/Sheet1/ole[2]"); // throws if <2 objects

// after
try { var ole = handler.Get("/Sheet1/ole[2]"); }
catch (ArgumentException) { /* ole index invalid */ }
Defensive patterns

Strategy: try-catch

Type guard

static int? ElementIndex(string cellRef, string element)
{
    var m = Regex.Match(cellRef, $@"^(?:ole|oleobject|object|embed)\[(\d+)$", RegexOptions.IgnoreCase);
    return m.Success && int.TryParse(m.Groups[1].Value, out var i) ? i : null;
}

Try / catch

try { return handler.Get("/Sheet1/ole[2]"); }
catch (ArgumentException ex) { /* ex.Message carries the available count */ return null; }

Prevention

When it happens

Trigger: handler.Get("/Sheet1/ole[2]") on a sheet with one (or zero) embedded objects. ole[0]. Using an alias like /Sheet1/object[1] on a sheet with no embeds.

Common situations: Assuming embedded objects exist on a sheet that has none. Hard-coded index after objects were removed. Zero-based indexing.

Related errors


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