{"record":{"id":"427807657f1631ba","repo":"iOfficeAI/OfficeCLI","slug":"name-property-is-required-for-namedrange","errorCode":null,"errorMessage":"'name' property is required for namedrange","messagePattern":"'name' property is required for namedrange","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs","lineNumber":44,"sourceCode":"        // still wins on mismatch, to keep other `/namedrange[N]` int\n        // indexing semantics elsewhere in the handler usable as-is).\n        var pathNrName = \"\";\n        {\n            var mNr = System.Text.RegularExpressions.Regex.Match(\n                parentPath, @\"^/namedrange\\[([^\\]]+)\\]/?$\",\n                System.Text.RegularExpressions.RegexOptions.IgnoreCase);\n            if (mNr.Success)\n            {\n                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)","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs#L26-L62","documentation":"Thrown when adding a named range and no name can be resolved. The name comes from the `name=` property, or, if absent, from a `namedrange[Name]` index capture in the parent path (only if the captured token is not a pure integer). If both are empty/null the throw fires. A defined name without an identifier is invalid OOXML, so this is a hard precondition.","triggerScenarios":"Calling `add /namedrange --type namedrange --prop ref=Sheet1!A1` with no `name=` and no path-derived name. Also when the path is `/namedrange[1]` (the bracketed index is an integer, so it is NOT promoted to a name) and no `name=` is given.","commonSituations":"Forgetting the name; assuming the index in `namedrange[1]` becomes the name (it does not — only non-integer captures do); using `title=` or `id=` instead of `name=`.","solutions":["Add `--prop name=MyRange`.","Or use a path capture like `/namedrange[MyRange]` (the non-integer bracket content is promoted to the name)."],"exampleFix":"// before\nadd ./book.xlsx /namedrange --type namedrange --prop ref=Sheet1!A1:B1\n// after\nadd ./book.xlsx /namedrange --type namedrange --prop name=SalesTotal --prop ref=Sheet1!A1:B1","handlingStrategy":"validation","validationCode":"// Resolve the name the way the handler does before calling add.\nvar name = props.GetValueOrDefault(\"name\") ?? PathDerivedName(path);\nif (string.IsNullOrEmpty(name))\n    throw new InvalidOperationException(\"namedrange requires a name (name= or /namedrange[Name])\");","typeGuard":"static bool HasNamedRangeName(IReadOnlyDictionary<string,string> p, string? pathName)\n    => !string.IsNullOrEmpty(p.GetValueOrDefault(\"name\"))\n    || !string.IsNullOrEmpty(pathName);","tryCatchPattern":"try { handler.AddNamedRange(...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"'name' property is required\"))\n{ /* prompt for the identifier */ }","preventionTips":["Always pass name= explicitly rather than relying on path capture.","Remember an integer bracket index (/namedrange[1]) is NOT promoted to a name."],"tags":["excel","named-range","missing-property","defined-name","input-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}