iOfficeAI/OfficeCLI · error · ArgumentException
Invalid majorUnit '{value}': must be a positive number (OOXM
Error message
Invalid majorUnit '{value}': must be a positive number (OOXML ST_AxisUnit > 0). What it means
Thrown when 'majorUnit' is not a positive number. OOXML ST_AxisUnit requires a double > 0; a value of 0 or negative makes Excel refuse to draw ticks (or freeze the chart in older builds). SafeParseDouble handles the non-numeric case separately; this throw fires only for a successfully parsed but non-positive number.
Source
Thrown at src/officecli/Core/Chart/ChartHelper.Setter.cs:1044
// Schema order: logBase?, orientation, max?, min? — insert max after orientation
var orient = scaling.GetFirstChild<C.Orientation>();
if (orient != null) orient.InsertAfterSelf(maxEl);
else scaling.PrependChild(maxEl);
break;
}
case "majorunit":
{
var plotArea2 = chart.GetFirstChild<C.PlotArea>();
var valAxis = plotArea2?.GetFirstChild<C.ValueAxis>();
if (valAxis == null) { unsupported.Add(key); break; }
var mu = ParseHelpers.SafeParseDouble(value, "majorunit");
// 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;
}
View on GitHub (pinned to 1ced45e900)
Solutions
- Pass a strictly positive majorUnit (e.g. 10, 0.5).
- If you want Excel to auto-compute the interval, omit majorUnit instead of sending 0.
- Compute the interval from the data range and guard against zero before calling Set.
Example fix
// before
SetChartProperties(part, new() { ["majorUnit"] = "0" });
// after
if (interval > 0)
SetChartProperties(part, new() { ["majorUnit"] = interval.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 majorUnit"))
{ /* omit majorUnit to let Excel auto-compute, or recompute from data */ } Prevention
- Compute intervals from the data range and guard against zero/negative before sending.
- If no explicit interval is needed, omit majorUnit entirely.
- Treat a computed interval of 0 as a data-pipeline bug, not a chart config.
When it happens
Trigger: SetChartProperties with { ["majorUnit"] = "0" }, "-5", or a parsed value that collapses to <= 0.
Common situations: Auto-generated tick interval of 0 from a data pipeline; sign error computing interval from data range; replaying a dump where the source chart had no majorUnit (empty) mis-encoded as 0.
Related errors
- axisMin={value} is invalid on a log-scaled axis: a logarithm
- Invalid minorUnit '{value}': must be a positive number (OOXM
- Invalid 'tickLabelPos' value: '{value}'. Valid: none, high,
- Invalid 'axisPos' value: '{value}'. Valid: top, bottom, left
- Invalid 'crosses' value: '{value}'. Valid: autoZero, max, mi
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/23244594c02e62e5.
Report an issue: GitHub.