{"record":{"id":"dccf83d4d6b5506b","repo":"iOfficeAI/OfficeCLI","slug":"cellref-spans-multiple-char-isdigit-cellref-0","errorCode":null,"errorMessage":"{cellRef} spans multiple {(char.IsDigit(cellRef[0]) ? \"rows\" : \"columns\")} — get them one at a time ({axisSegments[0]} … {axisSegments[^1]}); set accepts the whole span.","messagePattern":"(.+?) spans multiple (.+?) — get them one at a time \\((.+?) … (.+?)\\); set accepts the whole span\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Query.cs","lineNumber":906,"sourceCode":"                    ?? throw new ArgumentException(\n                        $\"Shape[{shpIndex}] not found in sheet '{sheetNameFromPath}' (indices are 1-based).\");\n            }\n\n\n            // If it looks like it could be a malformed cell reference (digits only, etc.), reject it\n            if (Regex.IsMatch(cellRef, @\"^\\d+$\"))\n                throw new ArgumentException($\"Invalid cell reference: '{cellRef}'. Expected format like 'A1', 'B2'.\");\n\n            // CONSISTENCY(axis-ref-compat): Excel-style whole-column/row\n            // references (B:B, 1:1) are input aliases for col[X]/row[N] —\n            // re-dispatch a single-axis span to the canonical path (readback\n            // Path stays canonical). Multi-axis spans (B:D) have no single\n            // node to return; point at the bracket syntax instead.\n            if (TryExpandAxisRef(cellRef) is { } axisSegments)\n            {\n                if (axisSegments.Count == 1)\n                    return Get($\"/{sheetNameFromPath}/{axisSegments[0]}\", depth);\n                throw new ArgumentException(\n                    $\"{cellRef} spans multiple {(char.IsDigit(cellRef[0]) ? \"rows\" : \"columns\")} — get them one at a time ({axisSegments[0]} … {axisSegments[^1]}); set accepts the whole span.\");\n            }\n\n            // Generic XML fallback: navigate worksheet XML tree\n            var xmlSegments = GenericXmlQuery.ParsePathSegments(cellRef);\n            var target = GenericXmlQuery.NavigateByPath(GetSheet(worksheet), xmlSegments);\n            if (target == null)\n                return new DocumentNode { Path = path, Type = \"error\", Text = $\"Element not found: {cellRef}\" };\n            return GenericXmlQuery.ElementToNode(target, path, depth);\n        }\n\n        // Handle /SheetName/A1/run[N] (rich text run direct access)\n        var runGetMatch = Regex.Match(cellRef, @\"^([A-Z]+\\d+)/run\\[(\\d+)\\]$\", RegexOptions.IgnoreCase);\n        if (runGetMatch.Success)\n        {\n            var runCellRef = runGetMatch.Groups[1].Value.ToUpperInvariant();\n            var runIdx = int.Parse(runGetMatch.Groups[2].Value);\n            ParseCellReference(runCellRef);","sourceCodeStart":888,"sourceCodeEnd":924,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Query.cs#L888-L924","documentation":"Thrown when a GET request uses a multi-axis span reference such as B:D (columns) or 1:5 (rows). TryExpandAxisRef accepts Excel-style whole-axis refs, but a span covering more than one column or row has no single node to return from Get. Single-axis aliases (B:B, 1:1) are re-dispatched to col[B]/row[1]; multi-axis spans are rejected and the message points at the bracket/set syntax that does accept a range.","triggerScenarios":"get /Sheet1/B:D, get /Sheet1/1:5, or any colon-span whose TryExpandAxisRef yields more than one segment. Triggered only on the read (Get) path — Set accepts the whole span.","commonSituations":"Treating Get like Set (Set tolerates ranges); pasting an Excel range selection (B:D) straight into a get path; assuming Get returns a list for a span when it is designed to return one node.","solutions":["Get each axis member individually: get /Sheet1/B then /Sheet1/C then /Sheet1/D.","Use the bracket selector for a range query: get /Sheet1/row[1:5] or query the column range via the col[] selector form.","If you need to write the span, use Set (set /Sheet1/B:D ...) which accepts the whole span."],"exampleFix":"// before\nget /Sheet1/B:D\n// after\nget /Sheet1/B\nget /Sheet1/C\nget /Sheet1/D","handlingStrategy":"validation","validationCode":"def is_multi_axis_span(seg):\n    # B:D or 1:5 style spans that cover >1 member are not gettable as one node\n    if ':' not in seg: return False\n    parts = seg.split(':')\n    if len(parts) != 2: return False\n    # same-type endpoints spanning more than one unit\n    return parts[0] != parts[1]\n\n# before a GET\nseg = 'B:D'\nassert not is_multi_axis_span(seg), 'GET needs one node; iterate members or use Set for the span'","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Remember Get returns a single node; only Set accepts a multi-axis span.","For range reads, query each member or use the row[1:5]/col[] selector form.","Detect ':' spans in the path before issuing a Get."],"tags":["excel","range","axis-ref","get","path"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}