{"record":{"id":"ff5fb0be617d4f05","repo":"iOfficeAI/OfficeCLI","slug":"invalid-defined-name-nrname-length-nrname-le","errorCode":null,"errorMessage":"Invalid defined-name '{nrName}': length {nrName.Length} exceeds the Excel 255-character limit.","messagePattern":"Invalid defined-name '(.+?)': length (.+?) exceeds the Excel 255-character limit\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs","lineNumber":59,"sourceCode":"        }\n        var nrName = properties.GetValueOrDefault(\"name\", pathNrName);\n        if (string.IsNullOrEmpty(nrName))\n            throw new ArgumentException(\"'name' property is required for namedrange\");\n        // Per OOXML §18.2.5: defined-name identifiers must start with\n        // letter/underscore/backslash, contain only letter/digit/\n        // underscore/period/backslash, and must not parse as a cell\n        // reference. Otherwise Excel rejects the file with 0x800A03EC.\n        // \"Letter\" is any Unicode letter (\\p{L}) — Excel accepts CJK/\n        // Cyrillic/etc. names; the previous ASCII-only class falsely\n        // rejected them. Emoji/symbols stay rejected (not \\p{L}).\n        if (!System.Text.RegularExpressions.Regex.IsMatch(nrName, @\"^[\\p{L}_\\\\][\\p{L}\\p{N}_\\\\.]*$\"))\n            throw new ArgumentException($\"Invalid defined-name '{nrName}': must start with a letter/underscore and contain only letters, digits, underscores, or periods (no spaces).\");\n        // Excel caps defined-name identifier length at 255 characters; longer\n        // names are silently truncated on open (or the file is rejected with\n        // 0x800A03EC depending on host). Refuse up front instead of letting\n        // a 256+ char name land on disk and round-trip-differ on re-open.\n        if (nrName.Length > 255)\n            throw new ArgumentException($\"Invalid defined-name '{nrName}': length {nrName.Length} exceeds the Excel 255-character limit.\");\n        if (LooksLikeCellReference(nrName))\n            throw new ArgumentException($\"Invalid defined-name '{nrName}': name parses as a cell reference; choose a different name.\");\n        // R39-5: Excel reserves the single letters R and C (case-insensitive)\n        // because they collide with R1C1 reference notation. Excel rejects\n        // the file with 0x800A03EC if either is used as a defined name.\n        if (nrName.Length == 1 && (nrName[0] == 'R' || nrName[0] == 'r' || nrName[0] == 'C' || nrName[0] == 'c'))\n            throw new ArgumentException($\"Invalid defined-name '{nrName}': single letter 'R' / 'C' is reserved by Excel for R1C1 reference notation; choose a different name.\");\n        // `refersTo` is the common Excel-documented alias for `ref`;\n        // silently map it so users don't end up with an empty\n        // <x:definedName/> that corrupts the file.\n        var refVal = properties.GetValueOrDefault(\"ref\",\n            properties.GetValueOrDefault(\"refersTo\",\n                properties.GetValueOrDefault(\"formula\", \"\")));\n        // R15/bt-2: reject up-front when the required ref/refersTo/formula\n        // value is missing so an empty <x:definedName/> never gets written\n        // (the resulting zombie polluted the workbook and broke later Set\n        // calls). Unsupported aliases like `range=` previously silently\n        // landed here as empty and produced the zombie.","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs#L41-L77","documentation":"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.","triggerScenarios":"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.","commonSituations":"Auto-generated names from a script concatenating many tokens; copying a long formula or description into the name field by mistake.","solutions":["Shorten the name to <= 255 characters.","Move the descriptive detail into a comment/label elsewhere and keep the identifier short."],"exampleFix":"// before\n--prop name=<256+ char string>\n// after\n--prop name=<short identifier under 255 chars>","handlingStrategy":"validation","validationCode":"const int MaxNameLen = 255;\nif (name.Length > MaxNameLen)\n    throw new InvalidOperationException($\"Defined-name length {name.Length} exceeds {MaxNameLen}\");","typeGuard":"static bool IsWithinDefinedNameLength(string? s) => (s?.Length ?? 0) <= 255;","tryCatchPattern":"try { handler.AddNamedRange(...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"255-character limit\"))\n{ /* truncate or reprompt for a shorter identifier */ }","preventionTips":["Keep defined-name identifiers short and descriptive.","If names are generated, cap the generator output well under 255 chars."],"tags":["excel","named-range","defined-name","length-limit","input-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}