{"record":{"id":"57bf7286b4f52558","repo":"iOfficeAI/OfficeCLI","slug":"invalid-defined-name-nrname-must-start-with-a","errorCode":null,"errorMessage":"Invalid defined-name '{nrName}': must start with a letter/underscore and contain only letters, digits, underscores, or periods (no spaces).","messagePattern":"Invalid defined-name '(.+?)': must start with a letter/underscore and contain only letters, digits, underscores, or periods \\(no spaces\\)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs","lineNumber":53,"sourceCode":"                var captured = mNr.Groups[1].Value;\n                // Only treat as a name if it is not a pure integer\n                // (preserves existing `/namedrange[1]` semantics).\n                if (!int.TryParse(captured, out _))\n                    pathNrName = captured;\n            }\n        }\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\",","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs#L35-L71","documentation":"Thrown when the resolved defined-name identifier fails the regex `^[\\p{L}_\\\\][\\p{L}\\p{N}_\\\\.]*$`. Per OOXML 18.2.5 a defined name must start with a Unicode letter, underscore, or backslash and contain only letters, digits, underscores, periods, or backslashes. Names with spaces, leading digits, emoji, or symbols would make Excel reject the file with 0x800A03EC, so they are refused up front. The regex intentionally allows any Unicode letter (\\p{L}) so CJK/Cyrillic names work.","triggerScenarios":"Passing `name=Sales Total` (space), `name=1stRange` (leading digit), `name=My-Range` (hyphen), `name=A+B` (operator), or an emoji-containing name. A leading underscore (`_hidden`) is allowed; a leading period is not.","commonSituations":"Using human-readable names with spaces; names matching variable names from another language that include disallowed chars; accidentally pasting a label rather than an identifier.","solutions":["Start the name with a letter or underscore and use only letters, digits, underscores, periods (e.g. `Sales_Total`, `Sales.Total`).","For names with spaces, replace spaces with underscores or remove them."],"exampleFix":"// before\nadd ./book.xlsx /namedrange --type namedrange --prop name=\"Sales Total\" --prop ref=Sheet1!A1\n// after\nadd ./book.xlsx /namedrange --type namedrange --prop name=Sales_Total --prop ref=Sheet1!A1","handlingStrategy":"validation","validationCode":"// Mirror the OOXML identifier grammar.\nif (!Regex.IsMatch(name, @\"^[\\p{L}_\\\\][\\p{L}\\p{N}_\\\\.]*$\"))\n    throw new InvalidOperationException(\n        $\"Invalid defined-name '{name}': bad characters or leading digit\");","typeGuard":"static bool IsValidDefinedNameIdentifier(string? s)\n    => s is not null\n    && System.Text.RegularExpressions.Regex.IsMatch(s, @\"^[\\p{L}_\\\\][\\p{L}\\p{N}_\\\\.]*$\");","tryCatchPattern":"try { handler.AddNamedRange(...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid defined-name\"))\n{ /* reprompt for a clean identifier */ }","preventionTips":["Start names with a letter or underscore; use only letters/digits/underscore/period.","Unicode letters (CJK, Cyrillic) are allowed, but avoid emoji and symbols.","Sanitize generated names: replace spaces/hyphens with underscores."],"tags":["excel","named-range","defined-name","identifier","input-validation","ooxml"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}