iOfficeAI/OfficeCLI · error · ArgumentException

Invalid 'crosses' value: '{value}'. Valid: autoZero, max, mi

Error message

Invalid 'crosses' value: '{value}'. Valid: autoZero, max, min.

What it means

Thrown when 'crosses' is not autoZero, max, or min (OOXML ST_Crosses). The value is validated BEFORE mutating so a bad input does not wipe the prior valid crosses value — a deliberate fix for a bug where a throw after RemoveAllChildren<Crosses> would silently drop a sibling. The new element is inserted in schema order (after crossAx, before crossesAt/crossBetween).

Source

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

                case "crosses":
                {
                    var plotArea2 = chart.GetFirstChild<C.PlotArea>();
                    var valAx = plotArea2?.GetFirstChild<C.ValueAxis>();
                    if (valAx == null) { unsupported.Add(key); break; }
                    // Remove only same-type predecessors. The pre-fix code also
                    // removed C.CrossesAt here, which silently wiped a sibling
                    // crossesAt value when both keys arrived in the same Set
                    // call (e.g. crosses + crossesAt + crossBetween together):
                    // the second branch reset both children and the first
                    // branch's write disappeared.
                    // Validate BEFORE mutating — a throw after RemoveAllChildren
                    // would wipe the prior valid crosses value on bad input.
                    var crossVal = value.ToLowerInvariant() switch
                    {
                        "max" => C.CrossesValues.Maximum,
                        "min" => C.CrossesValues.Minimum,
                        "autozero" => C.CrossesValues.AutoZero,
                        _ => throw new ArgumentException($"Invalid 'crosses' value: '{value}'. Valid: autoZero, max, min.")
                    };
                    valAx.RemoveAllChildren<C.Crosses>();
                    // CONSISTENCY(chart/crosses-schema-order): CT_ValAx requires
                    // crossAx → crosses → crossesAt → crossBetween. Insert
                    // before whichever later sibling exists.
                    var newCrosses = new C.Crosses { Val = crossVal };
                    var crossesAnchor = valAx.GetFirstChild<C.CrossesAt>() as OpenXmlElement
                        ?? valAx.GetFirstChild<C.CrossBetween>() as OpenXmlElement;
                    if (crossesAnchor != null) valAx.InsertBefore(newCrosses, crossesAnchor);
                    else valAx.AppendChild(newCrosses);
                    break;
                }

                case "crossesat":
                {
                    var plotArea2 = chart.GetFirstChild<C.PlotArea>();
                    var valAx = plotArea2?.GetFirstChild<C.ValueAxis>();
                    if (valAx == null) { unsupported.Add(key); break; }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use autoZero, max, or min.
  2. If you need a numeric crossing point, use 'crossesAt' instead of 'crosses'.
  3. Trim and ToLowerInvariant before passing.

Example fix

// before
SetChartProperties(part, new() { ["crosses"] = "atZero" });
// after
SetChartProperties(part, new() { ["crosses"] = "autoZero" });
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<string> Crosses =
    new[]{"autozero","max","min"}, StringComparer.OrdinalIgnoreCase);

static bool IsValidCrosses(string v) =>
    !string.IsNullOrWhiteSpace(v) && Crosses.Contains(v.Trim().ToLowerInvariant());

Type guard

static bool IsKnownCrosses(string v) =>
    (v?.Trim().ToLowerInvariant()) is "autozero" or "max" or "min";

Try / catch

try { SetChartProperties(part, props); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid 'crosses'"))
{ /* use crossesAt=<number> for a numeric crossing, or default to autoZero */ }

Prevention

When it happens

Trigger: SetChartProperties with { ["crosses"] = "middle" }, "atZero", or a misspelled token on the value axis.

Common situations: Mixing 'crosses' with 'crossesAt' vocabulary; typos; case sensitivity (only lowercase is matched).

Related errors


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