iOfficeAI/OfficeCLI · error · ArgumentException

Invalid defined-name '{nrName}': length {nrName.Length} exce

Error message

Invalid defined-name '{nrName}': length {nrName.Length} exceeds the Excel 255-character limit.

What it means

Thrown when the defined-name identifier exceeds 255 characters. Excel caps defined-name identifiers at 255; longer names are silently truncated on open or the file is rejected with 0x800A03EC. The guard refuses up front rather than letting a 256+ char name land on disk and round-trip-differ on re-open. This check runs after the character-class check (552) and before the cell-reference and R/C checks.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs:59

        }
        var nrName = properties.GetValueOrDefault("name", pathNrName);
        if (string.IsNullOrEmpty(nrName))
            throw new ArgumentException("'name' property is required for namedrange");
        // Per OOXML §18.2.5: defined-name identifiers must start with
        // letter/underscore/backslash, contain only letter/digit/
        // underscore/period/backslash, and must not parse as a cell
        // 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.

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Shorten the name to <= 255 characters.
  2. Move the descriptive detail into a comment/label elsewhere and keep the identifier short.

Example fix

// before
--prop name=<256+ char string>
// after
--prop name=<short identifier under 255 chars>
Defensive patterns

Strategy: validation

Validate before calling

const int MaxNameLen = 255;
if (name.Length > MaxNameLen)
    throw new InvalidOperationException($"Defined-name length {name.Length} exceeds {MaxNameLen}");

Type guard

static bool IsWithinDefinedNameLength(string? s) => (s?.Length ?? 0) <= 255;

Try / catch

try { handler.AddNamedRange(...); }
catch (ArgumentException ex) when (ex.Message.Contains("255-character limit"))
{ /* truncate or reprompt for a shorter identifier */ }

Prevention

When it happens

Trigger: Passing a programmatically generated or pasted name longer than 255 characters (e.g. a long descriptive label used as the identifier). The length is measured on the raw resolved nrName string.

Common situations: Auto-generated names from a script concatenating many tokens; copying a long formula or description into the name field by mistake.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/ff5fb0be617d4f05. Report an issue: GitHub.