iOfficeAI/OfficeCLI · error · ArgumentException

min={value} is invalid on a log-scaled axis: a logarithmic a

Error message

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

What it means

When setting an axis minimum on a secondary or non-primary axis (value2, category, series roles), the library checks whether that axis has a LogBase child element. A logarithmic axis cannot have min <= 0 — Excel refuses the file (error 0x800A03EC). The check reads the raw string value, parses it via SafeParseDouble, and throws if <= 0 with an existing log scale.

Source

Thrown at src/officecli/Core/Chart/ChartHelper.Axis.cs:278

                case "min":
                    // CONSISTENCY(chart/axis-role-write): the legacy `axismin` key
                    // always targets the primary value axis. For role=value2 we must
                    // write to the secondary axis directly to mirror BuildAxisNode's
                    // Skip(1) read path. Same for max/crosses/crossesat below.
                    // Category (date) and series axes must also write directly:
                    // the legacy `axismin` fallback targets the primary VALUE
                    // axis, which would clobber the wrong scaling.
                    if (normalizedRole is "value2" or "category" or "series"
                        && targetAxis is OpenXmlCompositeElement minAx2)
                    {
                        var scaling = minAx2.GetFirstChild<C.Scaling>();
                        if (scaling != null)
                        {
                            var minV = ParseHelpers.SafeParseDouble(value, "min");
                            // A log-scaled axis cannot have min <= 0 (Excel
                            // refuses the file, 0x800A03EC).
                            if (minV <= 0 && scaling.GetFirstChild<C.LogBase>() != null)
                                throw new ArgumentException(
                                    $"min={value} is invalid on a log-scaled axis: a logarithmic axis minimum must be greater than 0.");
                            scaling.RemoveAllChildren<C.MinAxisValue>();
                            // CT_Scaling order: logBase, orientation, max, min —
                            // min is last, so append is always valid.
                            scaling.AppendChild(new C.MinAxisValue { Val = minV });
                        }
                        directlyHandled.Add(key);
                    }
                    else
                    {
                        translated["axismin"] = value;
                    }
                    break;

                case "max":
                    if (normalizedRole is "value2" or "category" or "series"
                        && targetAxis is OpenXmlCompositeElement maxAx2)
                    {

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Set min to a positive value: axismin=1 or axismin=0.1.
  2. If you need min=0, first disable log scaling on that axis: logbase=0 or logbase=false.
  3. Verify which axis role you are targeting — value2, category, and series each hit this path independently.

Example fix

// before
logbase=10
axismin[value2]=0
// after
logbase=10
axismin[value2]=1
Defensive patterns

Strategy: validation

Validate before calling

static bool IsLogAxisMinValid(double minVal, bool hasLogBase)
    => !hasLogBase || minVal > 0;

// Before setting axismin on a value2/category/series axis:
var scaling = axis.GetFirstChild<C.Scaling>();
var hasLog = scaling?.GetFirstChild<C.LogBase>() != null;
var minVal = ParseHelpers.SafeParseDouble(value, "min");
if (!IsLogAxisMinValid(minVal, hasLog))
    throw new InvalidOperationException("min must be > 0 on a log-scaled axis.");

Try / catch

try { axisSetter.Apply("axismin", value); }
catch (ArgumentException ex) when (ex.Message.Contains("log-scaled axis"))
{
    Console.Error.WriteLine($"Disable log scale first (logbase=false) or use min > 0.");
}

Prevention

When it happens

Trigger: Setting axismin=0, axismin=-5, or any non-positive value on an axis that already has a C.LogBase element (log scaling enabled). This path is for non-primary value axes (value2, category, series roles); the primary value axis path is handled separately.

Common situations: Enabling log scale on a secondary axis then attempting to set min=0 (a common default for non-log axes). Copying a min=0 setting from a primary axis to a log-scaled secondary axis. Setting min before clearing the log scale.

Related errors


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