iOfficeAI/OfficeCLI · error · ArgumentException
Invalid defined-name '{nrName}': single letter 'R' / 'C' is
Error message
Invalid defined-name '{nrName}': single letter 'R' / 'C' is reserved by Excel for R1C1 reference notation; choose a different name. What it means
Thrown when the defined name is the single letter R or C (case-insensitive). Excel reserves these because they collide with R1C1 reference notation; using either as a workbook defined name makes Excel reject the file with 0x800A03EC. This is a targeted check that runs after the cell-reference check (554), so it specifically catches the R/C reservation that LooksLikeCellReference does not.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs:66
// reference. Otherwise Excel rejects the file with 0x800A03EC.
// "Letter" is any Unicode letter (\p{L}) — Excel accepts CJK/
// Cyrillic/etc. names; the previous ASCII-only class falsely
// rejected them. Emoji/symbols stay rejected (not \p{L}).
if (!System.Text.RegularExpressions.Regex.IsMatch(nrName, @"^[\p{L}_\\][\p{L}\p{N}_\\.]*$"))
throw new ArgumentException($"Invalid defined-name '{nrName}': must start with a letter/underscore and contain only letters, digits, underscores, or periods (no spaces).");
// Excel caps defined-name identifier length at 255 characters; longer
// names are silently truncated on open (or the file is rejected with
// 0x800A03EC depending on host). Refuse up front instead of letting
// a 256+ char name land on disk and round-trip-differ on re-open.
if (nrName.Length > 255)
throw new ArgumentException($"Invalid defined-name '{nrName}': length {nrName.Length} exceeds the Excel 255-character limit.");
if (LooksLikeCellReference(nrName))
throw new ArgumentException($"Invalid defined-name '{nrName}': name parses as a cell reference; choose a different name.");
// R39-5: Excel reserves the single letters R and C (case-insensitive)
// because they collide with R1C1 reference notation. Excel rejects
// the file with 0x800A03EC if either is used as a defined name.
if (nrName.Length == 1 && (nrName[0] == 'R' || nrName[0] == 'r' || nrName[0] == 'C' || nrName[0] == 'c'))
throw new ArgumentException($"Invalid defined-name '{nrName}': single letter 'R' / 'C' is reserved by Excel for R1C1 reference notation; choose a different name.");
// `refersTo` is the common Excel-documented alias for `ref`;
// silently map it so users don't end up with an empty
// <x:definedName/> that corrupts the file.
var refVal = properties.GetValueOrDefault("ref",
properties.GetValueOrDefault("refersTo",
properties.GetValueOrDefault("formula", "")));
// R15/bt-2: reject up-front when the required ref/refersTo/formula
// value is missing so an empty <x:definedName/> never gets written
// (the resulting zombie polluted the workbook and broke later Set
// calls). Unsupported aliases like `range=` previously silently
// landed here as empty and produced the zombie.
if (string.IsNullOrEmpty(refVal))
throw new ArgumentException("'ref' (or 'refersTo' / 'formula') property is required for namedrange");
// R7-2: per ECMA-376 §18.2.5, <x:definedName> content must NOT
// have a leading '=' (unlike the formula-bar form in Excel UI).
// Excel rejects the file with 0x800A03EC if '=' is present.
if (refVal.StartsWith('='))
refVal = refVal.TrimStart('=');View on GitHub (pinned to 1ced45e900)
Solutions
- Use a longer name like `RowRange`, `ColRange`, `R_Range`, or any name with more than one character.
- Avoid the single letters R and C entirely for defined names.
Example fix
// before add ./book.xlsx /namedrange --type namedrange --prop name=C --prop ref=Sheet1!C:C // after add ./book.xlsx /namedrange --type namedrange --prop name=ColRange --prop ref=Sheet1!C:C
Defensive patterns
Strategy: validation
Validate before calling
if (name.Length == 1 && (name[0] is 'R' or 'r' or 'C' or 'c'))
throw new InvalidOperationException("Defined name 'R'/'C' is reserved for R1C1 notation"); Type guard
static bool IsNotReservedRc(string? s)
=> s is null || s.Length != 1 || (s[0] is not 'R' and not 'r' and not 'C' and not 'c'); Try / catch
try { handler.AddNamedRange(...); }
catch (ArgumentException ex) when (ex.Message.Contains("reserved by Excel for R1C1"))
{ /* rename to something longer */ } Prevention
- Never use the single letters R or C as defined names.
- Use descriptive multi-character names like RowRange/ColRange.
When it happens
Trigger: Passing `name=R`, `name=r`, `name=C`, or `name=c`. These single letters pass the identifier regex and the cell-reference check but are independently reserved.
Common situations: Using `R` for a 'Row' range or `C` for a 'Column' range as a mnemonic; auto-generated single-letter names.
Related errors
- 'name' property is required for namedrange
- Invalid defined-name '{nrName}': must start with a letter/un
- Invalid defined-name '{nrName}': length {nrName.Length} exce
- Invalid defined-name '{nrName}': name parses as a cell refer
- 'ref' (or 'refersTo' / 'formula') property is required for n
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/ee7c8bdb81afd511.
Report an issue: GitHub.