{"record":{"id":"262a5e0ce0a4833b","repo":"iOfficeAI/OfficeCLI","slug":"invalid-cell-reference-cellref-expected-form","errorCode":null,"errorMessage":"Invalid cell reference: '{cellRef}'. Expected format like 'A1', 'B2'.","messagePattern":"Invalid cell reference: '(.+?)'\\. Expected format like 'A1', 'B2'\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Query.cs","lineNumber":895,"sourceCode":"                    ?? throw new ArgumentException(\n                        $\"Picture[{picIndex}] not found in sheet '{sheetNameFromPath}' (indices are 1-based).\");\n            }\n\n            // Handle shape[N] path segment\n            var shpMatch = Regex.Match(cellRef, @\"^shape\\[(\\d+)\\]$\", RegexOptions.IgnoreCase);\n            if (shpMatch.Success)\n            {\n                var shpIndex = int.Parse(shpMatch.Groups[1].Value);\n                // Same null-leak as picture[N] above.\n                return GetShapeNode(sheetNameFromPath, worksheet, shpIndex, path)\n                    ?? 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)","sourceCodeStart":877,"sourceCodeEnd":913,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Query.cs#L877-L913","documentation":"Thrown by the Excel Get path when the trailing path segment is pure digits (matches ^\\d+$), e.g. '/Sheet1/123'. A digit-only segment is neither a valid A1 cell reference nor a recognized element keyword (picture/shape/sparkline), so rather than letting it fall through to generic-XML navigation and return a misleading 'Element not found', the handler rejects it early with the expected A1 format.","triggerScenarios":"Calling get with a path whose cell-ref segment is all digits: get /Sheet1/42, or a range typo like /Sheet1/123:130 written without column letters. Also reached when a programmatic path builder emits an index where a cell coordinate belongs.","commonSituations":"Indexing loops that build paths as f\"/Sheet/{i}\" instead of f\"/Sheet/A{i}\"; copy-pasting row numbers from a spreadsheet into a path; confusing the positional row[N] bracket syntax (which is valid) with a bare digit segment.","solutions":["Prefix the row number with its column letter to form a real A1 reference, e.g. /Sheet1/A123 instead of /Sheet1/123.","If you meant a positional row, use the bracket form /Sheet1/row[123] (1-based), which is the canonical positional selector.","If you meant a whole row span, use /Sheet1/row[123] or the axis alias 123:123, not a bare 123."],"exampleFix":"// before\nget /Sheet1/123\n// after\nget /Sheet1/A123   // a specific cell\nget /Sheet1/row[123] // positional row","handlingStrategy":"validation","validationCode":"import re\ndef valid_cell_ref(seg):\n    # A1-style: one or more letters then digits, within sheet limits\n    m = re.fullmatch(r'([A-Za-z]+)(\\d+)', seg)\n    if not m: return False\n    col, row = m.group(1).upper(), int(m.group(2))\n    from functools import reduce\n    idx = reduce(lambda a, c: a * 26 + (ord(c) - 64), col, 0)\n    return 1 <= idx <= 16384 and 1 <= row <= 1048576\n\n# before building a get path\nseg = '123'\nassert valid_cell_ref(seg), f\"'{seg}' is not an A1 cell reference; use /Sheet1/row[N] for a positional row\"","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Always build cell paths as column-letter + row-number (A1), never a bare index.","Use the row[N] bracket form when you mean a positional row.","Validate generated path segments with an A1 regex before sending."],"tags":["excel","cell-reference","validation","get","path"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}