{"record":{"id":"41d32f5162d6637a","repo":"iOfficeAI/OfficeCLI","slug":"invalid-cell-reference-cellref","errorCode":null,"errorMessage":"Invalid cell reference: '{cellRef}'","messagePattern":"Invalid cell reference: '(.+?)'","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":400,"sourceCode":"                $\"Expected a cell reference (e.g. A2), cell[A2], or row[N].\");\n        }\n\n        string cellRef;\n        // BUG-R36-B1: when --prop arrayformula= is supplied with --prop ref=A1:C3,\n        // the range is the spill region, not a single cell address. Detect it and\n        // resolve cellRef to the top-left so FindOrCreateCell doesn't reject the\n        // colon. The full range is still passed through to arrayformula below via\n        // properties[\"ref\"].\n        string? arrayFormulaRefRange = null;\n        if (properties.ContainsKey(\"ref\"))\n        {\n            cellRef = properties[\"ref\"];\n            if (cellRef.Contains(':') && properties.ContainsKey(\"arrayformula\"))\n            {\n                arrayFormulaRefRange = cellRef;\n                var topLeft = cellRef.Split(':', 2)[0];\n                if (!Regex.IsMatch(topLeft, @\"^[A-Z]+\\d+$\", RegexOptions.IgnoreCase))\n                    throw new ArgumentException($\"Invalid cell reference: '{cellRef}'\");\n                cellRef = topLeft.ToUpperInvariant();\n            }\n            if (cellRefFromPath != null && !cellRefFromPath.Equals(cellRef, StringComparison.OrdinalIgnoreCase))\n                Console.Error.WriteLine($\"warning: path tail '{cellRefFromPath}' does not match --prop ref='{properties[\"ref\"]}'; using ref='{properties[\"ref\"]}'.\");\n        }\n        else if (properties.ContainsKey(\"address\"))\n        {\n            cellRef = properties[\"address\"];\n            if (cellRefFromPath != null && !cellRefFromPath.Equals(cellRef, StringComparison.OrdinalIgnoreCase))\n                Console.Error.WriteLine($\"warning: path tail '{cellRefFromPath}' does not match --prop address='{cellRef}'; using address='{cellRef}'.\");\n        }\n        else if (cellRefFromPath != null)\n        {\n            cellRef = cellRefFromPath;\n        }\n        else\n        {\n            // BUG-R41-B6: if the parent path supplies a row index (/Sheet1/row[5]),","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L382-L418","documentation":"When --prop ref= is supplied together with arrayformula=, the ref may be a spill range (e.g. A1:C3). AddCell resolves the cell to the range's top-left for FindOrCreateCell, but first validates that the top-left token matches the `^[A-Z]+\\d+$` cell-reference shape. If the colon-split first half is not a valid cell reference (malformed range), this throws rather than writing a corrupt anchor.","triggerScenarios":"Add(\"/Sheet1/A1\",\"cell\",pos,{[\"ref\"]=\"A1:bad\",[\"arrayformula\"]=\"...\"}); ref=\":C3\" (empty left side); ref=\"foo:B2\"; ref=\"1A:2B\"; any range whose left half fails the cell-ref regex.","commonSituations":"Building the spill range dynamically and producing a malformed range string; swapping the order of tokens in a range expression; an empty or whitespace left operand after splitting on ':'.","solutions":["Provide a well-formed range where both halves are valid A1 cell references, e.g. ref=\"A1:C3\".","Validate the range string with the regex ^[A-Z]+\\d+:[A-Z]+\\d+$ before passing it as ref.","If you only need a single-cell array formula, omit the colon and pass a single cell ref."],"exampleFix":"// before\nhandler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"ref\"] = left + \":\" + right, [\"arrayformula\"] = \"=B1:B3*C1:C3\" });\n// after\nif (Regex.IsMatch(left + \":\" + right, @\"^[A-Z]+\\d+:[A-Z]+\\d+$\"))\n    handler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"ref\"] = left + \":\" + right, [\"arrayformula\"] = \"=B1:B3*C1:C3\" });","handlingStrategy":"validation","validationCode":"if (props.TryGetValue(\"ref\", out var r) && r.Contains(':') && props.ContainsKey(\"arrayformula\"))\n{\n    var topLeft = r.Split(':', 2)[0];\n    if (!Regex.IsMatch(topLeft, @\"^[A-Z]+\\d+$\", RegexOptions.IgnoreCase))\n        throw new ArgumentException($\"Bad arrayformula range: {r}\");\n}\nh.Add(parentPath, \"cell\", pos, props);","typeGuard":"static bool IsValidCellRange(string r) =>\n    Regex.IsMatch(r, @\"^[A-Z]+\\d+:[A-Z]+\\d+$\", RegexOptions.IgnoreCase);","tryCatchPattern":"try { h.Add(parentPath, \"cell\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid cell reference\"))\n{ /* rebuild the ref range correctly */ }","preventionTips":["Construct ranges from two validated cell refs joined by ':'.","Validate the spill range before combining ref= with arrayformula=.","Avoid empty operands when splitting a range expression."],"tags":["excel","xlsx","cell","arrayformula","cell-ref","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}