{"record":{"id":"19af81bcca582750","repo":"iOfficeAI/OfficeCLI","slug":"invalid-cols-value-colsstr-expected-a-posi","errorCode":null,"errorMessage":"Invalid 'cols' value: '{colsStr}'. Expected a positive integer (number of columns to create).","messagePattern":"Invalid 'cols' value: '(.+?)'\\. Expected a positive integer \\(number of columns to create\\)\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":277,"sourceCode":"        {\n            newRow.Hidden = addRowHidden.Equals(\"true\", StringComparison.OrdinalIgnoreCase)\n                || addRowHidden == \"1\" || addRowHidden.Equals(\"yes\", StringComparison.OrdinalIgnoreCase);\n        }\n        // CONSISTENCY(add-set-symmetry): accept outline/group + collapsed at\n        // creation, mirroring SetRow (ExcelHandler.Set.cs L2823-2832).\n        if (parsedRowOutline is { } rowOutlineVal)\n            newRow.OutlineLevel = rowOutlineVal;\n        if (properties.TryGetValue(\"collapsed\", out var addRowCollapsed))\n        {\n            newRow.Collapsed = addRowCollapsed.Equals(\"true\", StringComparison.OrdinalIgnoreCase)\n                || addRowCollapsed == \"1\" || addRowCollapsed.Equals(\"yes\", StringComparison.OrdinalIgnoreCase);\n        }\n\n        // Create cells if cols specified\n        if (properties.TryGetValue(\"cols\", out var colsStr))\n        {\n            if (!int.TryParse(colsStr, out var cols) || cols <= 0)\n                throw new ArgumentException($\"Invalid 'cols' value: '{colsStr}'. Expected a positive integer (number of columns to create).\");\n            // CONSISTENCY(table-row-cN): pptx AddRow accepts c1=/c2=/... to\n            // populate the new row's cells (PowerPointHandler.Add.Table.cs\n            // L332). Mirror it here so xlsx `add row --prop cols=N c1=...`\n            // is a one-shot row create + fill instead of needing N follow-up\n            // cell Sets. Only materialize a <c> when the caller actually\n            // supplied content for that column — pre-emitting empty <c r=...>\n            // shells would diverge from Excel's stored form (empty cells are\n            // simply absent) and make Get(\"/Sheet/An\") report \"\" instead of\n            // \"(empty)\".\n            for (int c = 0; c < cols; c++)\n            {\n                if (!properties.TryGetValue($\"c{c + 1}\", out var cellText) || cellText == null)\n                    continue;\n                var colLetter = IndexToColumnName(c + 1);\n                EnsureCellValueLength(cellText, $\"{colLetter}{rowIdx}\");\n                var safe = OfficeCli.Core.PivotTableHelper.SanitizeXmlText(cellText);\n                var newCell = new Cell\n                {","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L259-L295","documentation":"AddRow's `cols` property pre-materializes that many cells in the new row (so you can fill them in one shot via c1=/c2=/...). It must be a strictly positive integer. A zero or negative value would loop zero/invalid times and a non-integer would be meaningless for a column count, so it is rejected up front.","triggerScenarios":"Add(\"/Sheet1\",\"row\",pos,{[\"cols\"]=\"0\"}); cols=\"-3\"; cols=\"2.5\" (fails int.TryParse); cols=\"three\" (not numeric); cols=\"\" (fails TryParse).","commonSituations":"Computing cols from a dynamic column count that can be 0 for an empty record; passing a floating-point column count; a templated call that left cols unset and defaulted to empty.","solutions":["Omit `cols` entirely when you do not need pre-created cells — the row is still created, and cells appear only where c1=/c2=... content is supplied.","Pass a positive integer equal to the number of cells you intend to populate.","Guard dynamic counts: if the computed cols is <=0, skip the Add or use a minimum of 1."],"exampleFix":"// before\nhandler.Add(\"/Sheet1\", \"row\", null, new() { [\"cols\"] = colCount.ToString() });\n// after\nif (colCount > 0)\n    handler.Add(\"/Sheet1\", \"row\", null, new() { [\"cols\"] = colCount.ToString(), [\"c1\"] = val });\nelse\n    handler.Add(\"/Sheet1\", \"row\", null, new());","handlingStrategy":"validation","validationCode":"if (props.TryGetValue(\"cols\", out var c) && (!int.TryParse(c, out var n) || n <= 0))\n    props.Remove(\"cols\"); // or throw, depending on intent\nh.Add(sheet, \"row\", pos, props);","typeGuard":"static bool IsValidColCount(string s) => int.TryParse(s, out var n) && n > 0;","tryCatchPattern":"try { h.Add(sheet, \"row\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"'cols' value\"))\n{ /* default to omitting cols or using 1 */ }","preventionTips":["Omit cols when you do not need pre-created cells.","Guard dynamic column counts against <= 0 before passing.","Prefer filling only the cells you have content for via c1=/c2=..."],"tags":["excel","xlsx","row","cols","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}