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
- Use autoZero, max, or min.
- If you need a numeric crossing point, use 'crossesAt' instead of 'crosses'.
- 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
- Distinguish 'crosses' (enum) from 'crossesAt' (numeric point).
- Whitelist crosses to autoZero/max/min.
- Trim and lowercase free-text input.
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
- axisMin={value} is invalid on a log-scaled axis: a logarithm
- Invalid majorUnit '{value}': must be a positive number (OOXM
- Invalid minorUnit '{value}': must be a positive number (OOXM
- Invalid 'tickLabelPos' value: '{value}'. Valid: none, high,
- Invalid 'axisPos' value: '{value}'. Valid: top, bottom, left
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/5940c4f1e86eef42.
Report an issue: GitHub.