{"record":{"id":"7e80deb3f9bca2be","repo":"iOfficeAI/OfficeCLI","slug":"invalid-referenceline-width-widthpt-tostring-g","errorCode":null,"errorMessage":"Invalid referenceLine width '{widthPt.ToString(\"G\", System.Globalization.CultureInfo.InvariantCulture)}'. Expected a positive number of points, typically 0.25–10.","messagePattern":"Invalid referenceLine width '(.+?)'\\. Expected a positive number of points, typically 0\\.25–10\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Chart/ChartHelper.Advanced.cs","lineNumber":95,"sourceCode":"        }\n        else if (parts.Length >= 5)\n        {\n            // Canonical 5-part form: value:color:width:dash:label (extra parts after label are joined\n            // back with ':' so labels containing literal colons survive a round-trip).\n            var widthStr = parts[2].Trim();\n            if (widthStr.Length > 0)\n            {\n                if (!double.TryParse(widthStr, System.Globalization.NumberStyles.Float,\n                        System.Globalization.CultureInfo.InvariantCulture, out widthPt))\n                    throw new ArgumentException(\n                        $\"Invalid referenceLine width '{widthStr}'. Expected a number in points (e.g. '1.5'), or empty for default {DefaultWidthPt}pt.\");\n            }\n            dash = parts[3].Trim();\n            label = string.Join(':', parts.Skip(4)).Trim();\n        }\n\n        if (widthPt <= 0 || widthPt > 100)\n            throw new ArgumentException(\n                $\"Invalid referenceLine width '{widthPt.ToString(\"G\", System.Globalization.CultureInfo.InvariantCulture)}'. Expected a positive number of points, typically 0.25–10.\");\n\n        // Warn: percent-stacked value axis is 0-1 (displayed 0%-100%). A refValue > 1\n        // is almost always a mistake — user likely forgot to convert 50 → 0.5.\n        // Without this check, Excel silently stretches the val axis to fit (e.g. 5000%),\n        // producing a chart where the real bars are compressed to a thin sliver on the left.\n        if (refValue > 1.0 && IsPercentStackedChart(plotArea))\n        {\n            var refMsg =\n                $\"referenceLine value {refValue.ToString(\"G\", System.Globalization.CultureInfo.InvariantCulture)} \"\n                + \"on a percent-stacked chart. The value axis is 0-1 (0%-100%); \"\n                + $\"did you mean {(refValue / 100.0).ToString(\"G\", System.Globalization.CultureInfo.InvariantCulture)}? \"\n                + \"Excel will auto-scale the axis to fit, compressing the real bars.\";\n            // CONSISTENCY(numfmt-warning): JSON mode → envelope warnings[];\n            // plain mode keeps the stderr line.\n            if (WarningContext.IsActive)\n                WarningContext.Add(refMsg, \"referenceline_out_of_scale\",\n                    $\"Use {(refValue / 100.0).ToString(\"G\", System.Globalization.CultureInfo.InvariantCulture)} for a 0-1 percent axis\");","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Chart/ChartHelper.Advanced.cs#L77-L113","documentation":"After successfully parsing the referenceLine width as a double, the library enforces a sanity range: widthPt must be strictly > 0 and <= 100. A non-positive width would be invisible or invalid in OOXML; an extremely large width (> 100pt) would be visually absurd and likely indicate a unit confusion (pixels vs points). The formatted value is shown in invariant (G) format.","triggerScenarios":"Passing a referenceLine width of 0, a negative number, or a value > 100 in the 5-part form: '50:FF0000:0:dash:Label', '50:FF0000:-1:dash:Label', '50:FF0000:200:dash:Label'.","commonSituations":"Using 0 thinking it means 'default' (use empty string instead). Passing pixel values (e.g. 200px) without unit conversion. Negative widths from a calculation error. Confusing the width slot with the value slot.","solutions":["Use a positive width in the range 0.25–10pt: '50:FF0000:2:dash:Label'.","If you want the default width, leave the width segment empty: '50:FF0000::dash:Label'.","Convert pixel values to points (1pt ≈ 1.33px at 96 DPI) before passing."],"exampleFix":"// before\nreferenceline: \"50:FF0000:200:dash:Target\"\n// after\nreferenceline: \"50:FF0000:2:dash:Target\"","handlingStrategy":"validation","validationCode":"static bool IsRefLineWidthInRange(string spec)\n{\n    var parts = spec.Split(':');\n    if (parts.Length < 5) return true;\n    var widthStr = parts[2].Trim();\n    if (widthStr.Length == 0) return true;\n    if (!double.TryParse(widthStr, System.Globalization.NumberStyles.Float,\n        System.Globalization.CultureInfo.InvariantCulture, out var w)) return false;\n    return w > 0 && w <= 100;\n}","typeGuard":null,"tryCatchPattern":"try { ChartHelperAdvanced.AddReferenceLine(chart, spec); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Expected a positive number of points\"))\n{\n    Console.Error.WriteLine($\"Width out of range. Use 0.25–10pt or leave empty for default.\");\n}","preventionTips":["Keep reference line width in the 0.25–10pt range.","Leave the width empty for the default rather than passing 0.","Convert pixel values to points (1pt ≈ 1.33px at 96 DPI)."],"tags":["chart","reference-line","range-check","invalid-value"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}