{"record":{"id":"5162a92e58957ec9","repo":"iOfficeAI/OfficeCLI","slug":"invalid-combotypes-token-t-expected-bar-colum","errorCode":null,"errorMessage":"Invalid comboTypes token '{t}'. Expected bar/column/line/area/scatter, optionally with a stacked/percentstacked suffix (e.g. 'column,line' or 'columnstacked,line').","messagePattern":"Invalid comboTypes token '(.+?)'\\. Expected bar/column/line/area/scatter, optionally with a stacked/percentstacked suffix \\(e\\.g\\. 'column,line' or 'columnstacked,line'\\)\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Chart/ChartHelper.Advanced.cs","lineNumber":517,"sourceCode":"    /// </summary>\n    internal static void RebuildComboChart(C.Chart chart, string comboTypes)\n    {\n        var plotArea = chart.GetFirstChild<C.PlotArea>();\n        if (plotArea == null) return;\n\n        var typeList = comboTypes.Split(',').Select(t => t.Trim().ToLowerInvariant()).ToArray();\n\n        // Validate every token BEFORE any mutation: unknown tokens used to fall\n        // through to the default LineChart arm, silently coercing garbage\n        // (combotypes=asdf,qwer) into line,line — the only mini-language prop\n        // that accepted typos. Also keeps the rebuild atomic on bad input.\n        foreach (var t in typeList)\n        {\n            var baseToken = t.EndsWith(\"percentstacked\", StringComparison.Ordinal) ? t[..^14]\n                : t.EndsWith(\"stacked\", StringComparison.Ordinal) ? t[..^7]\n                : t;\n            if (baseToken is not (\"bar\" or \"column\" or \"col\" or \"line\" or \"area\" or \"scatter\"))\n                throw new ArgumentException(\n                    $\"Invalid comboTypes token '{t}'. Expected bar/column/line/area/scatter, \" +\n                    \"optionally with a stacked/percentstacked suffix (e.g. 'column,line' or 'columnstacked,line').\");\n        }\n\n        // Read all existing series data\n        var allSer = plotArea.Descendants<OpenXmlCompositeElement>()\n            .Where(e => e.LocalName == \"ser\").ToList();\n\n        if (allSer.Count == 0) return;\n\n        // Read series data\n        var seriesInfo = new List<(OpenXmlCompositeElement original, string targetType)>();\n        for (int i = 0; i < allSer.Count; i++)\n        {\n            var targetType = i < typeList.Length ? typeList[i] : typeList[^1];\n            seriesInfo.Add((allSer[i], targetType));\n        }\n","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Chart/ChartHelper.Advanced.cs#L499-L535","documentation":"The comboTypes setter splits a comma-separated list of chart type tokens, strips optional 'stacked' or 'percentstacked' suffixes, and validates each base token against {bar, column, col, line, area, scatter}. Validation runs BEFORE any mutation to keep the rebuild atomic — unknown tokens used to silently fall through to the default LineChart arm, coercing garbage into line charts. Only the mini-language property that previously accepted typos.","triggerScenarios":"Passing a comboTypes value containing an unrecognized type token: 'column,asdf', 'pie,line', 'xyzstacked,bar'. The token (after suffix stripping) must be one of bar/column/col/line/area/scatter.","commonSituations":"Typing a chart type that is valid as a standalone chart but not as a combo member (e.g. 'pie' or 'doughnut' — combos only support bar/column/line/area/scatter). Misspelling 'column' as 'colunm' or 'colum'. Using 'colstacked' (valid) but with an unknown base like 'col2stacked'.","solutions":["Use only bar, column (or col), line, area, or scatter as combo types: 'column,line'.","Append 'stacked' or 'percentstacked' suffix for variants: 'columnstacked,line'.","Do not use pie, doughnut, radar, stock, or bubble in comboTypes — they are not supported in combo charts."],"exampleFix":"// before\ncombotypes: \"column,pie\"\n// after\ncombotypes: \"column,line\"\n// stacked variant\ncombotypes: \"columnstacked,line\"","handlingStrategy":"validation","validationCode":"static readonly HashSet<string> ValidComboBaseTokens = new()\n{ \"bar\", \"column\", \"col\", \"line\", \"area\", \"scatter\" };\n\nstatic bool AreComboTypesValid(string comboTypes)\n{\n    foreach (var t in comboTypes.Split(',').Select(x => x.Trim().ToLowerInvariant()))\n    {\n        var baseToken = t.EndsWith(\"percentstacked\", StringComparison.Ordinal) ? t[..^14]\n            : t.EndsWith(\"stacked\", StringComparison.Ordinal) ? t[..^7]\n            : t;\n        if (!ValidComboBaseTokens.Contains(baseToken)) return false;\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try { ChartHelperAdvanced.ApplyComboTypes(plotArea, comboTypes); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Invalid comboTypes token\"))\n{\n    Console.Error.WriteLine($\"{ex.Message}\\nValid: bar, column, line, area, scatter (with optional stacked/percentstacked suffix).\");\n}","preventionTips":["Combo types only support bar, column, line, area, scatter — not pie, doughnut, or radar.","Spell-check type tokens before passing them.","Validate each token against the allowed set programmatically."],"tags":["chart","combo","chart-type","invalid-value"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}