{"record":{"id":"42c6da58ce08a587","repo":"iOfficeAI/OfficeCLI","slug":"table-index-tidx-out-of-range-1-tparts-count","errorCode":null,"errorMessage":"Table index {tIdx} out of range (1..{tParts.Count})","messagePattern":"Table index (.+?) out of range \\(1\\.\\.(.+?)\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Query.cs","lineNumber":823,"sourceCode":"\n        // Table path: /Sheet1/table[N]\n        var tableMatch = Regex.Match(cellRef, @\"^table\\[(\\d+)\\]$\", RegexOptions.IgnoreCase);\n        if (tableMatch.Success)\n        {\n            var tableIdx = int.Parse(tableMatch.Groups[1].Value);\n            return TableToNode(sheetNameFromPath, worksheet, tableIdx, depth);\n        }\n\n        // Table column path: /Sheet1/table[N]/columns[M] or /column[M]\n        var tableColMatch = Regex.Match(cellRef,\n            @\"^table\\[(\\d+)\\]/(?:columns|column)\\[(\\d+)\\]$\", RegexOptions.IgnoreCase);\n        if (tableColMatch.Success)\n        {\n            var tIdx = int.Parse(tableColMatch.Groups[1].Value);\n            var cIdx = int.Parse(tableColMatch.Groups[2].Value);\n            var tParts = worksheet.TableDefinitionParts.ToList();\n            if (tIdx < 1 || tIdx > tParts.Count)\n                throw new ArgumentException($\"Table index {tIdx} out of range (1..{tParts.Count})\");\n            var tbl = tParts[tIdx - 1].Table\n                ?? throw new ArgumentException($\"Table {tIdx} has no definition\");\n            var tCols = tbl.GetFirstChild<TableColumns>()?.Elements<TableColumn>().ToList();\n            if (tCols == null || cIdx < 1 || cIdx > tCols.Count)\n                throw new ArgumentException($\"Column index {cIdx} out of range (1..{tCols?.Count ?? 0})\");\n            var tCol = tCols[cIdx - 1];\n            var tcNode = new DocumentNode\n            {\n                Path = $\"/{sheetNameFromPath}/table[{tIdx}]/columns[{cIdx}]\",\n                Type = \"tableColumn\",\n                Text = tCol.Name?.Value ?? \"\"\n            };\n            tcNode.Format[\"name\"] = tCol.Name?.Value ?? \"\";\n            if (tCol.Id?.Value != null) tcNode.Format[\"id\"] = tCol.Id.Value;\n            if (tCol.TotalsRowFunction?.HasValue == true)\n                // Open XML SDK v3 EnumValue<T>.ToString() returns\n                // \"TotalsRowFunctionValues { }\" — use InnerText for the\n                // OOXML-canonical lowercase token. CONSISTENCY(enum-innertext).","sourceCodeStart":805,"sourceCodeEnd":841,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Query.cs#L805-L841","documentation":"Thrown for /Sheet/table[N]/columns[M] when N exceeds the sheet's TableDefinitionParts.Count (1-based). Each worksheet owns its own table-definition parts, so the valid range is per-sheet (shown in the message as 1..count). A workbook-global table index won't match.","triggerScenarios":"handler.Get(\"/Sheet1/table[3]/columns[1]\") on a sheet with fewer than 3 tables. table[0]. Using a workbook-wide table index where a per-sheet index is required.","commonSituations":"Hard-coded table index after tables were removed. Wrong sheet. Zero-based indexing. Reusing an index counted across the whole workbook.","solutions":["Enumerate via the /table bare lister (lists every table as /Sheet/table[N]) and use a valid per-sheet N.","Use a 1-based index in [1, perSheetTableCount].","try/catch(ArgumentException) and read the (1..N) range from the message."],"exampleFix":"// before\nvar col = handler.Get(\"/Sheet1/table[3]/columns[1]\"); // throws if <3 tables\n\n// after\nvar sheetTables = handler.Get(\"/table\").Children\n    .Where(c => c.Path.StartsWith(\"/Sheet1/table[\", StringComparison.OrdinalIgnoreCase))\n    .ToList();\nif (sheetTables.Count == 0) return null;\nvar col = handler.Get(sheetTables[0].Path + \"/columns[1]\");","handlingStrategy":"validation","validationCode":"// the /table bare lister enumerates every table as /Sheet/table[N]\nvar sheetTables = handler.Get(\"/table\").Children\n    .Where(c => c.Path.StartsWith($\"/{sheet}/table[\", StringComparison.OrdinalIgnoreCase))\n    .ToList();\nif (tIdx < 1 || tIdx > sheetTables.Count) return null;\nreturn handler.Get($\"/{sheet}/table[{tIdx}]/columns[{cIdx}]\");","typeGuard":"static int? ElementIndex(string cellRef, string element)\n{\n    var m = Regex.Match(cellRef, $@\"^{Regex.Escape(element)}\\[(\\d+)$\", RegexOptions.IgnoreCase);\n    return m.Success && int.TryParse(m.Groups[1].Value, out var i) ? i : null;\n}","tryCatchPattern":null,"preventionTips":["Table indices are per-sheet and 1-based — a workbook-wide index won't match.","Enumerate via the /table lister to discover valid per-sheet indices.","Don't hard-code a table index after tables are added or removed."],"tags":["excel","tables","tablecolumn","path-index","argument-exception"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}