{"record":{"id":"7c5bca3540980a0d","repo":"iOfficeAI/OfficeCLI","slug":"invalid-referenceline-width-widthstr-expected","errorCode":null,"errorMessage":"Invalid referenceLine width '{widthStr}'. Expected a number in points (e.g. '1.5'), or empty for default {DefaultWidthPt}pt.","messagePattern":"Invalid referenceLine width '(.+?)'\\. Expected a number in points \\(e\\.g\\. '1\\.5'\\), or empty for default (.+?)pt\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Chart/ChartHelper.Advanced.cs","lineNumber":87,"sourceCode":"                widthPt = w4;\n                dash = p3;\n            }\n            else\n            {\n                label = p2;\n                dash = p3;\n            }\n        }\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)} \"","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Chart/ChartHelper.Advanced.cs#L69-L105","documentation":"In the canonical 5-part referenceLine form (value:color:width:dash:label), parts[2] is the line width in points. If the width segment is non-empty and fails double.TryParse (InvariantCulture), the library rejects it. An empty width segment is valid and defaults to DefaultWidthPt. This only applies to the 5-part form; the 3-part form treats parts[2] as a label.","triggerScenarios":"Passing a referenceLine spec with 5+ colon-separated segments where the third segment (width) is non-numeric: '50:FF0000:thick:dash:Label'. The spec must have >= 5 parts to enter this code path.","commonSituations":"Confusing the 3-part form (value:color:label) with the 5-part form (value:color:width:dash:label) and placing a non-numeric string in the width slot. Using locale-specific decimal separators in the width ('1,5' instead of '1.5').","solutions":["Ensure the width segment (parts[2] in the 5-part form) is a numeric value in points: '50:FF0000:1.5:dash:Label'.","Leave the width segment empty to use the default: '50:FF0000::dash:Label'.","If you intended a 3-part form with a label, remember that parts[2] in a 3-part spec is the label, not the width — add width only in the 5-part form."],"exampleFix":"// before\nreferenceline: \"50:FF0000:thick:dash:Target\"\n// after\nreferenceline: \"50:FF0000:1.5:dash:Target\"\n// or empty width for default\nreferenceline: \"50:FF0000::dash:Target\"","handlingStrategy":"validation","validationCode":"static bool TryValidateRefLineWidth(string spec)\n{\n    var parts = spec.Split(':');\n    if (parts.Length < 5) return true; // 5-part form only\n    var widthStr = parts[2].Trim();\n    if (widthStr.Length == 0) return true; // empty = default\n    return double.TryParse(widthStr, System.Globalization.NumberStyles.Float,\n        System.Globalization.CultureInfo.InvariantCulture, out _);\n}","typeGuard":null,"tryCatchPattern":"try { ChartHelperAdvanced.AddReferenceLine(chart, spec); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid referenceLine width\") && ex.Message.Contains(\"Expected a number\"))\n{\n    Console.Error.WriteLine($\"Width segment is non-numeric. Use a number or leave empty for default.\");\n}","preventionTips":["Remember the 5-part form is value:color:width:dash:label — width is parts[2].","Leave the width segment empty to use the default.","Use dot-decimal format for the width value."],"tags":["chart","reference-line","number-parsing","invalid-value"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}