{"record":{"id":"a4102d296203157e","repo":"iOfficeAI/OfficeCLI","slug":"invalid-length-value-value-must-be-non-negati","errorCode":null,"errorMessage":"Invalid length value '{value}'. Must be non-negative.","messagePattern":"Invalid length value '(.+?)'\\. Must be non-negative\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/SpacingConverter.cs","lineNumber":123,"sourceCode":"    /// unit-qualified \"12pt\", \"0.5cm\", \"0.5in\", \"-1cm\", \"-12pt\", or a bare\n    /// signed number (treated as points). Used for PPTX paragraph indent\n    /// which permits hanging-indent style negatives. CONSISTENCY(pptx-bare-as-points).\n    /// </summary>\n    public static double ParsePointsSigned(string value)\n    {\n        return ParseSpacingToPointsSigned(value, bareIsPoints: true);\n    }\n\n    /// <summary>\n    /// Parse a length value to points. Accepts unit-qualified \"12pt\", \"0.5cm\",\n    /// \"0.5in\" or bare number (treated as points). Used for XLSX shape margin\n    /// to mirror Get's \"Npt\" output. CONSISTENCY(spacing-units).\n    /// </summary>\n    public static double ParsePoints(string value)\n    {\n        var points = ParseSpacingToPoints(value, bareIsPoints: true);\n        if (points < 0)\n            throw new ArgumentException($\"Invalid length value '{value}'. Must be non-negative.\");\n        return points;\n    }\n\n    // ────────────────────────────────────────────────────────────────\n    //  lineSpacing  →  Word (twips + LineRule)\n    // ────────────────────────────────────────────────────────────────\n\n    /// <summary>\n    /// Parse line spacing for Word. Returns (twips, isMultiplier).\n    /// \"1.5x\" or \"150%\" → (360, true)  — Auto rule, 240 × multiplier\n    /// \"18pt\"           → (360, true=false) — Exact rule, pt × 20\n    /// \"0.5cm\"          → converted to pt, then Exact\n    /// bare number      → (number, true) — Auto rule, backward compat (raw twips)\n    /// </summary>\n    public static (int Twips, bool IsMultiplier) ParseWordLineSpacing(string value)\n    {\n        var trimmed = value.Trim();\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/SpacingConverter.cs#L105-L141","documentation":"Thrown by ParsePoints when the parsed length value is negative. ParsePoints is used for non-negative length slots such as XLSX shape margins, treating bare numbers as points (CONSISTENCY spacing-units). Different message text ('length ... Must be non-negative') distinguishes it from the spacing guard. ArgumentException.","triggerScenarios":"Passing a negative length to a slot routed through ParsePoints — e.g. an Excel shape margin ('-5pt') or any handler using EmuConverter via ParsePoints.","commonSituations":"A negative value intended for an offset/indent is applied to a margin that must be non-negative, or a signed measurement leaks into a length field.","solutions":["Use a non-negative length (e.g. '5pt', '0').","If a negative offset is genuinely needed, confirm the target property accepts it and use the signed parser path.","Check you are setting a margin, not an indent."],"exampleFix":"// before\nset shape margin left=-5pt\n// after\nset shape margin left=5pt","handlingStrategy":"validation","validationCode":"var pts = SpacingConverter.ParsePoints(value);\nif (pts < 0) throw new ArgumentException($\"Non-negative length required: {value}\");\n// For offsets that allow negatives, use ParsePointsSigned.","typeGuard":null,"tryCatchPattern":"try { var pts = SpacingConverter.ParsePoints(value); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Must be non-negative\"))\n{ /* use a non-negative length */ }","preventionTips":["Keep length/margin values non-negative.","Use ParsePointsSigned only for slots that accept negatives (e.g. PPTX indent).","Confirm the property semantics before passing a negative."],"tags":["length","excel","argument","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}