{"record":{"id":"d433e6b41c0c7222","repo":"iOfficeAI/OfficeCLI","slug":"invalid-range-value-afrange-expected-a-cel","errorCode":null,"errorMessage":"Invalid 'range' value: '{afRange}'. Expected a cell range like 'A1:F100' or 'A1'.","messagePattern":"Invalid 'range' value: '(.+?)'\\. Expected a cell range like 'A1:F100' or 'A1'\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs","lineNumber":747,"sourceCode":"        // path naturally.\n        if (properties is OfficeCli.Core.TrackingPropertyDictionary afTracking)\n        {\n            var consumed = properties.Keys\n                .Where(k => string.Equals(k, \"range\", StringComparison.OrdinalIgnoreCase)\n                    || Regex.IsMatch(k, @\"^criteria\\d+\\.[A-Za-z]+$\"))\n                .ToList();\n            afTracking.MarkAllConsumed(consumed);\n        }\n\n        var afRange = properties.GetValueOrDefault(\"range\")\n            ?? throw new ArgumentException(\"AutoFilter requires 'range' property (e.g. range=A1:F100)\");\n\n        // CONSISTENCY(cellref-validate): reject garbage refs (e.g. \"BADREF\")\n        // so Excel doesn't silently open with an invalid <x:autoFilter ref=\"...\">.\n        if (!Regex.IsMatch(afRange.Trim(),\n                @\"^\\$?[A-Z]+\\$?\\d+(?::\\$?[A-Z]+\\$?\\d+)?$\",\n                RegexOptions.IgnoreCase))\n            throw new ArgumentException(\n                $\"Invalid 'range' value: '{afRange}'. Expected a cell range like 'A1:F100' or 'A1'.\");\n        // Canonicalize inverted input (D5:A1) like the rest of the range family.\n        afRange = NormalizeA1Range(afRange);\n\n        // CONSISTENCY(autofilter-table-dup): a Table already owns its own\n        // <autoFilter> internally; layering a sheet-level <autoFilter> over\n        // the same range produces the duplicate that Excel rejects with a\n        // \"found a problem\" repair dialog. Mirror the T4 overlap check\n        // used by AddTable.\n        var afRangeUpper = afRange.ToUpperInvariant();\n        foreach (var existingTdp in afWorksheet.TableDefinitionParts)\n        {\n            var existingTable = existingTdp.Table;\n            if (existingTable?.Reference?.Value is string existingTableRef\n                && RangesOverlap(afRangeUpper, existingTableRef.ToUpperInvariant()))\n                throw new ArgumentException(\n                    $\"AutoFilter range '{afRangeUpper}' overlaps existing table \" +\n                    $\"'{existingTable.Name?.Value ?? existingTable.DisplayName?.Value}' \" +","sourceCodeStart":729,"sourceCodeEnd":765,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs#L729-L765","documentation":"Thrown by AddAutoFilter when the supplied range (trimmed) does not match ^\\$?[A-Z]+\\$?\\d+(?::\\$?[A-Z]+\\$?\\d+)?$. It accepts a single cell or a Cell:Cell rectangle with optional $ anchors; anything else (garbage tokens, whole-column forms like A:A, or a sheet-prefixed ref) is rejected so Excel does not silently open with an invalid <x:autoFilter ref>.","triggerScenarios":"Call Add type \"autofilter\" with range set to a malformed value such as \"BADREF\", \"A:A\" (whole column, no row), \"Sheet1!A1:F100\" (sheet prefix), or \"A1::F100\".","commonSituations":"Passing a whole-column range (the regex requires a row number); including the sheet name in the range; extra colons; non-A1 tokens from a selector copy-paste.","solutions":["Use a single cell (\"A1\") or a rectangle (\"A1:F100\"), with optional $ anchors.","Drop any sheet prefix from the range value (the sheet comes from parentPath).","For a whole column, give explicit rows (e.g. \"A1:A1048576\")."],"exampleFix":"// before\nhandler.Add(\"/Sheet1\", \"autofilter\", null, new() { [\"range\"] = \"Sheet1!A1:F100\" });\n// after\nhandler.Add(\"/Sheet1\", \"autofilter\", null, new() { [\"range\"] = \"A1:F100\" });","handlingStrategy":"validation","validationCode":"var r = properties.GetValueOrDefault(\"range\", \"\").Trim();\nif (!Regex.IsMatch(r, @\"^\\$?[A-Z]+\\$?\\d+(?::\\$?[A-Z]+\\$?\\d+)?$\", RegexOptions.IgnoreCase))\n    throw new InvalidOperationException($\"Invalid AutoFilter range '{r}'; use A1 or A1:F100\");","typeGuard":"static bool IsValidAutoFilterRange(string? r) =>\n    r is not null && Regex.IsMatch(r.Trim(),\n        @\"^\\$?[A-Z]+\\$?\\d+(?::\\$?[A-Z]+\\$?\\d+)?$\", RegexOptions.IgnoreCase);","tryCatchPattern":null,"preventionTips":["The regex requires a row number; whole-column 'A:A' is rejected (use A1:A1048576).","Do not include the sheet name in the range value (sheet comes from parentPath).","Allow optional $ anchors but avoid extra colons or selectors."],"tags":["excel","autofilter","cell-reference","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}