iOfficeAI/OfficeCLI · error · ArgumentException

Invalid minorUnit '{value}': must be a positive number (OOXM

Error message

Invalid minorUnit '{value}': must be a positive number (OOXML ST_AxisUnit > 0).

What it means

Thrown when 'minorUnit' is not a positive number — the same ST_AxisUnit constraint as majorUnit. Non-numeric input is rejected earlier by SafeParseDouble; this throw covers a parsed value <= 0.

Source

Thrown at src/officecli/Core/Chart/ChartHelper.Setter.cs:1057

                    // OOXML ST_AxisUnit: positive double. 0 or negative would
                    // make Excel refuse to draw any tick on the axis (or, in
                    // older builds, freeze the chart). Reject up front instead
                    // of writing garbage that opens to a blank plot area.
                    if (!(mu > 0))
                        throw new ArgumentException($"Invalid majorUnit '{value}': must be a positive number (OOXML ST_AxisUnit > 0).");
                    valAxis.RemoveAllChildren<C.MajorUnit>();
                    InsertValAxChildInOrder(valAxis, new C.MajorUnit { Val = mu });
                    break;
                }

                case "minorunit":
                {
                    var plotArea2 = chart.GetFirstChild<C.PlotArea>();
                    var valAxis = plotArea2?.GetFirstChild<C.ValueAxis>();
                    if (valAxis == null) { unsupported.Add(key); break; }
                    var nu = ParseHelpers.SafeParseDouble(value, "minorunit");
                    if (!(nu > 0))
                        throw new ArgumentException($"Invalid minorUnit '{value}': must be a positive number (OOXML ST_AxisUnit > 0).");
                    valAxis.RemoveAllChildren<C.MinorUnit>();
                    InsertValAxChildInOrder(valAxis, new C.MinorUnit { Val = nu });
                    break;
                }

                case "axisnumfmt" or "axisnumberformat":
                {
                    var plotArea2 = chart.GetFirstChild<C.PlotArea>();
                    var valAxis = plotArea2?.GetFirstChild<C.ValueAxis>();
                    if (valAxis == null) { unsupported.Add(key); break; }
                    valAxis.RemoveAllChildren<C.NumberingFormat>();
                    var nf = new C.NumberingFormat { FormatCode = value, SourceLinked = false };
                    // Schema order: ...title, numFmt, majorTickMark... — insert before majorTickMark
                    var nfInsertBefore = valAxis.GetFirstChild<C.MajorTickMark>();
                    if (nfInsertBefore != null) valAxis.InsertBefore(nf, nfInsertBefore);
                    else valAxis.AppendChild(nf);
                    break;
                }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Pass a strictly positive minorUnit, typically less than majorUnit.
  2. Omit minorUnit to let Excel auto-derive it.
  3. Guard computed values: if (nu <= 0) skip the key.

Example fix

// before
SetChartProperties(part, new() { ["minorUnit"] = "0" });
// after
var minor = major / 2.0;
if (minor > 0)
    SetChartProperties(part, new() { ["minorUnit"] = minor.ToString(CultureInfo.InvariantCulture) });
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidAxisUnit(string v, out double unit) =>
    double.TryParse(v, NumberStyles.Float, CultureInfo.InvariantCulture, out unit)
    && unit > 0;

Type guard

static bool IsPositiveUnit(double v) => v > 0 && !double.IsInfinity(v);

Try / catch

try { SetChartProperties(part, props); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid minorUnit"))
{ /* omit minorUnit to let Excel auto-derive */ }

Prevention

When it happens

Trigger: SetChartProperties with { ["minorUnit"] = "0" } or a negative number.

Common situations: Reusing majorUnit as minorUnit without halving it; defaulting to 0 when the source had no minor tick; data-driven interval that underflows to 0.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/36ed72e3ba52b125. Report an issue: GitHub.