iOfficeAI/OfficeCLI · error · ArgumentException
trendline.period must be >= 2 (OOXML ST_Skip MinInclusive=2)
Error message
trendline.period must be >= 2 (OOXML ST_Skip MinInclusive=2). Got: {periodVal}. What it means
Thrown by ApplyTrendlineOptions (ChartHelper.SetterHelpers.cs:183) when the dotted key trendline.period (or the period slot of a BuildTrendline spec via the separate code path) receives an integer below 2. Same OOXML ST_Skip MinInclusive=2 constraint as error 184; this is the post-build per-property setter path rather than the build-spec path. The pre-fix code clamped silently, hiding invalid input from callers, so it now throws.
Source
Thrown at src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs:183
case "forward" or "forecastforward":
trendline.RemoveAllChildren<C.Forward>();
trendline.AppendChild(new C.Forward { Val = ParseHelpers.SafeParseDouble(value, "trendline.forward") });
break;
case "backward" or "forecastbackward":
trendline.RemoveAllChildren<C.Backward>();
trendline.AppendChild(new C.Backward { Val = ParseHelpers.SafeParseDouble(value, "trendline.backward") });
break;
case "order":
trendline.RemoveAllChildren<C.PolynomialOrder>();
trendline.AppendChild(new C.PolynomialOrder { Val = (byte)Math.Clamp(ParseHelpers.SafeParseInt(value, "trendline.order"), 2, 6) });
break;
case "period":
{
// OOXML ST_Skip MinInclusive=2. Pre-fix code clamped < 2 to 2;
// silently coerce hid invalid input from callers. Throw instead.
var periodVal = ParseHelpers.SafeParseInt(value, "trendline.period");
if (periodVal < 2)
throw new ArgumentException($"trendline.period must be >= 2 (OOXML ST_Skip MinInclusive=2). Got: {periodVal}.");
trendline.RemoveAllChildren<C.Period>();
trendline.AppendChild(new C.Period { Val = (uint)periodVal });
break;
}
case "intercept":
trendline.RemoveAllChildren<C.Intercept>();
trendline.AppendChild(new C.Intercept { Val = ParseHelpers.SafeParseDouble(value, "trendline.intercept") });
break;
case "disprsqr" or "rsquared" or "r2" or "displayrsquared":
{
// CT_Trendline schema order (per ECMA-376 §21.2.2.211):
// ... intercept → dispRSqr → dispEq → trendlineLbl → extLst
// dispRSqr comes BEFORE dispEq. Anchor on the first later-
// schema sibling so both Set orders produce valid XML.
trendline.RemoveAllChildren<C.DisplayRSquaredValue>();
var newRsqr = new C.DisplayRSquaredValue { Val = ParseHelpers.IsTruthy(value) };
var rsqrAnchor = (OpenXmlElement?)trendline.GetFirstChild<C.DisplayEquation>()
?? trendline.GetFirstChild<C.TrendlineLabel>();View on GitHub (pinned to 1ced45e900)
Solutions
- Set trendline.period to an integer >= 2.
- Only set period on moving-average trendlines — it is not meaningful for other types.
Example fix
// before series1.trendline.period=1 // after series1.trendline.period=3
Defensive patterns
Strategy: validation
Validate before calling
static int ResolveTrendlinePeriod(string value)
{
var p = ParseHelpers.SafeParseInt(value, "trendline.period");
return p >= 2 ? p : throw new ArgumentException("trendline.period must be >= 2");
} Type guard
static bool IsValidTrendlinePeriod(string value) =>
int.TryParse(value, out var p) && p >= 2; Try / catch
try { /* set series1.trendline.period=N */ }
catch (ArgumentException ex) when (ex.Message.Contains("trendline.period must be >= 2"))
{ /* prompt for a value >= 2 */ } Prevention
- Only set trendline.period on moving-average trendlines.
- Clamp UI input to a minimum of 2 before sending.
- Treat 0/1 as 'use default (2)' rather than forwarding the raw value.
When it happens
Trigger: Setting series1.trendline.period=0, series1.trendline.period=1, or chart-level trendline.period=1 on a moving-average trendline.
Common situations: Driving period from a variable that defaults to 0/1; setting period generically across trendline types without knowing moving-average's floor; replaying a dumped period that was edited down.
Related errors
- movingAvg period must be >= 2 (OOXML ST_Skip MinInclusive=2)
- {fullKey}: expected boolean (true/false/1/0/yes/no/on/off),
- invalid_value
- Chart type '{chartType}' is not supported. OOXML has no Scat
- DefinedName '{trimmedInput}' not found
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/4fa638db803672da.
Report an issue: GitHub.