{"record":{"id":"061ec4003c3334fc","repo":"iOfficeAI/OfficeCLI","slug":"invalid-lower-value-must-be-a-positive-numb","errorCode":null,"errorMessage":"Invalid {lower} '{value}': must be a positive number (OOXML ST_AxisUnit > 0).","messagePattern":"Invalid (.+?) '(.+?)': must be a positive number \\(OOXML ST_AxisUnit > 0\\)\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Chart/ChartHelper.Axis.cs","lineNumber":690,"sourceCode":"\n                case \"majorunit\":\n                case \"minorunit\":\n                {\n                    // Schema: majorUnit / minorUnit only valid on value/value2.\n                    // Without this direct-apply branch the role-scoped Set on\n                    // role=value2 falls through to the chart-level case which\n                    // always grabs the primary ValueAxis, so the secondary\n                    // axis silently retained its old tick interval.\n                    if (normalizedRole is not (\"value\" or \"value2\"))\n                    {\n                        directlyHandled.Add(key);\n                        break;\n                    }\n                    if (targetAxis is OpenXmlCompositeElement axMu)\n                    {\n                        var unit = ParseHelpers.SafeParseDouble(value, lower);\n                        if (!(unit > 0))\n                            throw new ArgumentException(\n                                $\"Invalid {lower} '{value}': must be a positive number (OOXML ST_AxisUnit > 0).\");\n                        if (lower == \"majorunit\")\n                        {\n                            axMu.RemoveAllChildren<C.MajorUnit>();\n                            InsertValAxChildInOrder(axMu, new C.MajorUnit { Val = unit });\n                        }\n                        else\n                        {\n                            axMu.RemoveAllChildren<C.MinorUnit>();\n                            InsertValAxChildInOrder(axMu, new C.MinorUnit { Val = unit });\n                        }\n                    }\n                    directlyHandled.Add(key);\n                    break;\n                }\n\n                case \"majorgridlines\":\n                case \"minorgridlines\":","sourceCodeStart":672,"sourceCodeEnd":708,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Chart/ChartHelper.Axis.cs#L672-L708","documentation":"The majorUnit/minorUnit setter applies to value axes only (value or value2 roles). The value is parsed as a double via SafeParseDouble, then checked to be strictly > 0 (OOXML ST_AxisUnit requires positive). A non-positive unit is invalid. The element (C.MajorUnit or C.MinorUnit) is then inserted in CT_ValAx schema order via InsertValAxChildInOrder.","triggerScenarios":"Setting majorunit or minorunit to 0, a negative number, or a value that parses to <= 0: majorunit=0, minorunit=-5. Only fires for value/value2 axis roles.","commonSituations":"Using 0 expecting it to mean 'auto' (OOXML has no auto for major/minor unit via this element — leave the element unset for auto). Using a negative value from a calculation error. Setting unit on a category axis (silently ignored, does not throw).","solutions":["Use a strictly positive value: majorunit=10, minorunit=2.","To use Excel's auto-calculation for major/minor unit, remove the element entirely (do not set it).","Ensure the unit is smaller than the axis range to avoid invisible gridlines."],"exampleFix":"// before\nmajorunit=0\n// after\nmajorunit=10\n// for auto unit, leave unset\n// majorunit: (not set)","handlingStrategy":"validation","validationCode":"static bool IsValidAxisUnit(string value)\n{\n    if (!double.TryParse(value, System.Globalization.NumberStyles.Float,\n        System.Globalization.CultureInfo.InvariantCulture, out var unit))\n        return false;\n    return unit > 0;\n}","typeGuard":null,"tryCatchPattern":"try { axisSetter.Apply(lower, value); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"ST_AxisUnit\"))\n{\n    Console.Error.WriteLine($\"{ex.Message}\\nMust be a positive number. Leave unset for auto.\");\n}","preventionTips":["Use a strictly positive value for majorUnit/minorUnit.","Leave the property unset to use Excel's auto-calculation.","Validate the parsed double is > 0 before applying."],"tags":["chart","axis","major-unit","minor-unit","range-check","ooxml-schema"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}