iOfficeAI/OfficeCLI · error · ArgumentException

axisMin={value} is invalid on a log-scaled axis: a logarithm

Error message

axisMin={value} is invalid on a log-scaled axis: a logarithmic axis minimum must be greater than 0.

What it means

Thrown when 'axisMin'/'min' is set to a value <= 0 on an axis that already has a C.LogBase child. A logarithmic axis cannot start at zero or a negative number — real Excel refuses the file with 0x800A03EC. The setter validates the combined axis state (value + presence of LogBase) before mutating C.Scaling.

Source

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

                            ?? (OpenXmlElement?)catAxis.GetFirstChild<C.MajorGridlines>()
                            ?? catAxis.GetFirstChild<C.AxisPosition>();
                        if (insertAfter != null) catAxis.InsertAfter(BuildChartTitle(value), insertAfter);
                    }
                    break;
                }

                case "axismin" or "min":
                {
                    var plotArea2 = chart.GetFirstChild<C.PlotArea>();
                    var valAxis = plotArea2?.GetFirstChild<C.ValueAxis>();
                    var scaling = valAxis?.GetFirstChild<C.Scaling>();
                    if (scaling == null) { unsupported.Add(key); break; }
                    var minVal = ParseHelpers.SafeParseDouble(value, "axismin");
                    // A log-scaled axis cannot have min <= 0 — real Excel refuses
                    // the file (0x800A03EC). Validate the combined state before
                    // mutating.
                    if (minVal <= 0 && scaling.GetFirstChild<C.LogBase>() != null)
                        throw new ArgumentException(
                            $"axisMin={value} is invalid on a log-scaled axis: a logarithmic axis minimum must be greater than 0.");
                    scaling.RemoveAllChildren<C.MinAxisValue>();
                    scaling.AppendChild(new C.MinAxisValue { Val = minVal });
                    break;
                }

                case "axismax" or "max":
                {
                    var plotArea2 = chart.GetFirstChild<C.PlotArea>();
                    var valAxis = plotArea2?.GetFirstChild<C.ValueAxis>();
                    var scaling = valAxis?.GetFirstChild<C.Scaling>();
                    if (scaling == null) { unsupported.Add(key); break; }
                    scaling.RemoveAllChildren<C.MaxAxisValue>();
                    var maxEl = new C.MaxAxisValue { Val = ParseHelpers.SafeParseDouble(value, "axismax") };
                    // 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);

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Set axisMin to a strictly positive value (> 0) when the axis is log-scaled.
  2. If you do not need an explicit minimum on a log axis, omit axisMin entirely and let Excel auto-scale.
  3. Order your batch so logScale is applied before min only if you intentionally want to clear min, but prefer a positive value regardless.

Example fix

// before
SetChartProperties(part, new() { ["logScale"] = "true", ["axisMin"] = "0" });
// after
SetChartProperties(part, new() { ["logScale"] = "true", ["axisMin"] = "1" });
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidAxisMin(double min, bool isLogScale) =>
    !double.IsNaN(min) && !double.IsInfinity(min) && (!isLogScale || min > 0);

Type guard

static bool IsLegalLogAxisMin(string val, bool logScale, out double min) =>
    double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out min)
    && (!logScale || min > 0);

Try / catch

try { SetChartProperties(part, props); }
catch (ArgumentException ex) when (ex.Message.Contains("log-scaled axis"))
{ /* drop axisMin or set it to a positive value and retry */ }

Prevention

When it happens

Trigger: SetChartProperties with { ["axisMin"] = "0" } or a negative number on a chart whose value axis already carries logBase; or applying min= and logScale= in the same batch where min resolves first.

Common situations: Defaulting axis minimum to 0 on a template later switched to log scale; replaying a dump that captured min=0 before the log-scale flag was set; scientific/financial dashboards that auto-zero baselines.

Related errors


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