iOfficeAI/OfficeCLI · error · ArgumentException
Cell reference '{cellRef.Replace("\n", "\\n").Replace("\r",
Error message
Cell reference '{cellRef.Replace("\n", "\\n").Replace("\r", "\\r")}' contains invalid control characters. Expected a clean cell address like 'A1' or 'B2'. What it means
Thrown when the cell-reference segment (the part after the sheet, e.g. A1 in /Sheet1/A1) contains ASCII control characters (except tab) or DEL (0x7F). The guard exists because .NET regex '$' anchors before a trailing \n, so a value like 'A1\n' would otherwise pass the cell-ref check and silently resolve to a non-existent 'ghost' cell (BUG-R41-F2). Rejecting it surfaces the bad input instead of returning phantom data.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Query.cs:455
sheetNode.Format["colBreaks"] = string.Join(",", cbreaks);
}
if (depth > 0)
{
sheetNode.Children = GetSheetChildNodes(sheetNameFromPath, data, depth, worksheet);
// Children omit value-less empty cells/rows (issue #149);
// reflect the actual listed count, not the raw row count.
sheetNode.ChildCount = sheetNode.Children.Count;
}
return sheetNode;
}
// BUG-R41-F2: reject cell reference segments that contain control characters
// (e.g. \n, \r, \t). Without this check, "A1\n" passes the cell-ref regex
// (Regex `$` matches before trailing \n in .NET) and resolves to a ghost cell.
var cellRef = segments[1];
if (cellRef.Any(c => c < ' ' && c != '\t' || c == '\x7f'))
throw new ArgumentException(
$"Cell reference '{cellRef.Replace("\n", "\\n").Replace("\r", "\\r")}' contains invalid control characters. " +
$"Expected a clean cell address like 'A1' or 'B2'.");
// Page break path: /Sheet1/rowbreak[N] or /Sheet1/colbreak[N]
var rbMatch = Regex.Match(cellRef, @"^rowbreak\[(\d+)\]$", RegexOptions.IgnoreCase);
if (rbMatch.Success)
{
var rbIdx = int.Parse(rbMatch.Groups[1].Value);
var rowBreaks = GetSheet(worksheet).GetFirstChild<RowBreaks>();
var breaks = rowBreaks?.Elements<Break>().ToList() ?? new();
if (rbIdx < 1 || rbIdx > breaks.Count)
throw new ArgumentException($"Row break index {rbIdx} out of range (1-{breaks.Count})");
var brk = breaks[rbIdx - 1];
var rbNode = new DocumentNode
{
Path = path, Type = "rowbreak",
Format = { ["row"] = brk.Id?.Value ?? 0u, ["manual"] = brk.ManualPageBreak?.Value ?? false }
};View on GitHub (pinned to 1ced45e900)
Solutions
- Sanitize the path before Get: strip chars in \x00-\x08, \x0B, \x0C, \x0E-\x1F, \x7F (keep tab only if intended).
- .Trim() the cell segment and reject empty results.
- Validate with a clean cell-ref regex (^[A-Za-z]{1,3}[0-9]+$) before calling Get.
Example fix
// before
var cell = handler.Get("/Sheet1/" + addr); // addr = "A1\n" -> throws
// after
var clean = Regex.Replace(addr, @"[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]", "").Trim();
var cell = handler.Get($"/Sheet1/{clean}"); Defensive patterns
Strategy: validation
Validate before calling
// strip control chars (except tab) + DEL before Get
var clean = Regex.Replace(path, @"[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]", "");
if (clean != path)
throw new ArgumentException("Path contained control characters");
return handler.Get(clean); Type guard
static bool HasControlChars(string cellRef) =>
cellRef.Any(c => (c < ' ' && c != '\t') || c == '\x7f'); Prevention
- Sanitize every path built from user/clipboard/DB input before Get.
- .Trim() cell segments and reject empties.
- Validate cell refs against ^[A-Za-z]{1,3}[0-9]+$ before use.
When it happens
Trigger: Calling Get with a cell segment carrying \n/\r/\t from unsanitized user input, a clipboard paste, or string concatenation — e.g. handler.Get("/Sheet1/A1\n") or /Sheet1/B2\r. Reading addresses from a DB/CSV column that has trailing newlines.
Common situations: Pasting an address from a cell that includes a newline. Interpolating values read from another source without trimming. Cross-platform line endings (\r\n) leaking into a path segment.
Related errors
- pivot name contains invalid control characters
- Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D
- Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:
- Invalid anchor: '{picAnchorRaw}'. Expected e.g. 'B2', 'B2:E6
- Invalid anchor: '{shpAnchorStr}'. Expected e.g. 'B2' or 'B2:
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/eaed0d4f5394ac30.
Report an issue: GitHub.