{"record":{"id":"4b6eb57202f9147b","repo":"iOfficeAI/OfficeCLI","slug":"invalid-value-4b6eb5","errorCode":"invalid_value","errorMessage":"Invalid trendline type '{parts[0]}'. Valid: linear, exp, log, poly, power, movingAvg. For per-series different trendlines use seriesN.trendline keys, not pipe-separated lists.","messagePattern":"Invalid trendline type '(.+?)'\\. Valid: linear, exp, log, poly, power, movingAvg\\. For per-series different trendlines use seriesN\\.trendline keys, not pipe-separated lists\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs","lineNumber":81,"sourceCode":"\n    internal static C.Trendline BuildTrendline(string spec)\n    {\n        // Format: \"type\" or \"type:order\" or \"type:forward:backward\"\n        // e.g. \"linear\", \"poly:3\", \"exp:2:1\", \"movingAvg:3\"\n        var parts = spec.Split(':');\n        var typeStr = parts[0].Trim().ToLowerInvariant();\n\n        var trendline = new C.Trendline();\n\n        var trendType = typeStr switch\n        {\n            \"linear\" => C.TrendlineValues.Linear,\n            \"exp\" or \"exponential\" => C.TrendlineValues.Exponential,\n            \"log\" or \"logarithmic\" => C.TrendlineValues.Logarithmic,\n            \"poly\" or \"polynomial\" => C.TrendlineValues.Polynomial,\n            \"power\" => C.TrendlineValues.Power,\n            \"movingavg\" or \"moving\" or \"movingaverage\" => C.TrendlineValues.MovingAverage,\n            _ => throw new CliException(\n                $\"Invalid trendline type '{parts[0]}'. \" +\n                \"Valid: linear, exp, log, poly, power, movingAvg. \" +\n                \"For per-series different trendlines use seriesN.trendline keys, \" +\n                \"not pipe-separated lists.\")\n                { Code = \"invalid_value\" }\n        };\n        trendline.AppendChild(new C.TrendlineType { Val = trendType });\n\n        // Polynomial order or moving average period\n        if (parts.Length > 1 && int.TryParse(parts[1], out var order))\n        {\n            if (trendType == C.TrendlineValues.Polynomial)\n                trendline.AppendChild(new C.PolynomialOrder { Val = (byte)Math.Clamp(order, 2, 6) });\n            else if (trendType == C.TrendlineValues.MovingAverage)\n            {\n                // OOXML ST_Skip MinInclusive=2 (c:period inside c:trendline).\n                // Pre-fix code silently accepted order=0/1 which Word 422s on.\n                if (order < 2)","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs#L63-L99","documentation":"Thrown by BuildTrendline (ChartHelper.SetterHelpers.cs:81) as a CliException with Code='invalid_value' when the first colon-separated slot of a trendline spec does not match linear, exp/exponential, log/logarithmic, poly/polynomial, power, or movingavg/moving/movingaverage. The message also directs users who want per-series different trendlines to use seriesN.trendline keys instead of pipe-separated lists. Unlike most chart parsers this one throws a CliException (structured code) rather than a plain ArgumentException.","triggerScenarios":"Setting trendline=<spec> where spec's type slot is unrecognized, e.g. 'spline', 'avg', 'std', 'exponential2' (no separator), 'polyomial' (typo). Also when trying to apply multiple different trendlines via a pipe list to a single seriesN.trendline key.","commonSituations":"Abbreviating 'movingAvg' as 'avg' or 'ma'; typoing 'polynomial'/'logarithmic'; attempting 'spline' which OOXML does not support; passing a pipe list like 'linear|poly:3' to one key instead of separate seriesN.trendline keys.","solutions":["Use a supported type: linear, exp, log, poly, power, movingAvg (aliases: exponential, logarithmic, polynomial, moving, movingAverage).","For per-series different trendlines, set seriesN.trendline=<spec> per series rather than a pipe-separated list.","For multiple trendlines on one series, join specs with semicolons (e.g. series1.trendline=linear;poly:3), not pipes."],"exampleFix":"// before\nseries1.trendline=avg:3\n// after\nseries1.trendline=movingAvg:3","handlingStrategy":"validation","validationCode":"static readonly HashSet<string> TrendlineTypes = new(StringComparer.OrdinalIgnoreCase)\n{ \"linear\",\"exp\",\"exponential\",\"log\",\"logarithmic\",\"poly\",\"polynomial\",\"power\",\"movingavg\",\"moving\",\"movingaverage\" };\nstatic string ValidateTrendlineSpec(string spec)\n{\n    var typeStr = spec.Split(':')[0].Trim().ToLowerInvariant();\n    return TrendlineTypes.Contains(typeStr) ? typeStr : throw new ArgumentException($\"invalid trendline type '{spec}'\");\n}","typeGuard":"static bool IsValidTrendlineType(string spec) =>\n    TrendlineTypes.Contains((spec.Split(':')[0]).Trim().ToLowerInvariant());","tryCatchPattern":"try { /* set series1.trendline=... */ }\ncatch (CliException ex) when (ex.Code == \"invalid_value\" && ex.Message.Contains(\"Invalid trendline type\"))\n{ /* list supported types, suggest per-series keys */ }","preventionTips":["Use seriesN.trendline per series for different trendlines; join multiple on one series with ';'.","Do not use pipe-separated lists for trendlines.","Validate the type slot before adding order/period suffixes."],"tags":["chart","trendline","validation","invalid-value"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}