{"record":{"id":"ce1f61ac0260b7f4","repo":"iOfficeAI/OfficeCLI","slug":"datarange-resolved-to-0-series-columns-a-single-c","errorCode":null,"errorMessage":"dataRange resolved to 0 series columns: a single-column range is consumed as the category column by default. Pass categories= explicitly (e.g. categories=Sheet1!A1:A5) to plot that column as a series, or widen the dataRange to include a values column.","messagePattern":"dataRange resolved to 0 series columns: a single-column range is consumed as the category column by default\\. Pass categories= explicitly \\(e\\.g\\. categories=Sheet1!A1:A5\\) to plot that column as a series, or widen the dataRange to include a values column\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Chart.cs","lineNumber":82,"sourceCode":"            // categories=A1:A4) rather than a literal list, ParseSeriesData/\n            // ParseCategories leave the literal values empty (the range is only\n            // emitted as a numRef/strRef formula). Real Excel — and the\n            // `dataRange=` path here — also snapshot the referenced cells into\n            // a numCache/strCache so the chart renders before the workbook is\n            // re-evaluated (the HTML preview plots only from that cache).\n            // Resolve the ranges against the worksheet now to backfill the\n            // literal values, mirroring ParseDataRangeForChart.\n            BackfillSeriesRangeValues(ref seriesData, ref categories, chartSheetName, properties);\n        }\n\n        if (seriesData.Count == 0)\n        {\n            // A supplied-but-consumed dataRange must not get the generic\n            // \"requires a data property\" message: with a single-column range\n            // and no explicit categories=, the sole column is reserved as\n            // the category column, leaving zero series — say so.\n            if (properties.ContainsKey(\"dataRange\") || properties.ContainsKey(\"datarange\"))\n                throw new ArgumentException(\n                    \"dataRange resolved to 0 series columns: a single-column range is consumed as the \" +\n                    \"category column by default. Pass categories= explicitly (e.g. categories=Sheet1!A1:A5) \" +\n                    \"to plot that column as a series, or widen the dataRange to include a values column.\");\n            throw new ArgumentException(\"Chart requires a 'data' property. Use: data=\\\"Series1:1,2,3;Series2:4,5,6\\\" \" +\n                \"or dataRange=\\\"Sheet1!A1:D5\\\" or series1=\\\"Revenue:100,200,300\\\"\");\n        }\n\n        // Validate the chart type BEFORE any part is created: an unknown type\n        // used to throw inside the builder AFTER the DrawingsPart and its\n        // sheet relationship were attached, leaving an orphaned empty\n        // <xdr:wsDr/> part behind on every failed attempt. Extended (cx)\n        // types — funnel/treemap/… — route through ChartExBuilder below and\n        // must not be run through the classic-type parser.\n        if (!ChartExBuilder.IsExtendedChartType(chartType))\n            ChartHelper.ParseChartType(chartType);\n\n        // Create DrawingsPart if needed\n        var drawingsPart = chartWorksheet.DrawingsPart","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Chart.cs#L64-L100","documentation":"Thrown when a chart-add call supplies a dataRange that resolves to zero plottable series. With a single-column range and no explicit categories=, the library reserves that sole column as the category axis, leaving nothing to plot as values. The message is deliberately specific (instead of the generic 'requires a data property') so the user knows the dataRange was consumed, not ignored.","triggerScenarios":"Calling chart Add with properties containing 'dataRange' (or 'datarange') pointing to a single-column range (e.g. Sheet1!A1:A5) and no 'categories' key, after BackfillSeriesRangeValues leaves seriesData.Count == 0. The dataRange key check is case-insensitive via ContainsKey on both spellings.","commonSituations":"User has a column of labels or numbers and passes it as dataRange expecting it to be plotted as the data series. Common when migrating from a tool that treats a single column as values rather than categories. Also happens when a multi-column range reference has a typo that collapses it to one column.","solutions":["Add a second column to the dataRange so at least one column survives as a values series (e.g. dataRange=Sheet1!A1:B5).","Pass categories= explicitly with a separate range so the single dataRange column is freed to become a series (e.g. categories=Sheet1!A1:A5 dataRange=Sheet1!B1:B5).","Switch from dataRange to the data= property with inline values: data=\"Series1:1,2,3\".","Use series1=/series2= properties for per-series literal data: series1=\"Revenue:100,200,300\"."],"exampleFix":"// before\nadd /Sheet1/chart --type chart --chartType bar --dataRange Sheet1!A1:A5\n// after (widen to include a values column)\nadd /Sheet1/chart --type chart --chartType bar --dataRange Sheet1!A1:B5","handlingStrategy":"validation","validationCode":"// Before calling chart Add, verify the dataRange spans >= 2 columns\nif (properties.ContainsKey(\"dataRange\") || properties.ContainsKey(\"datarange\"))\n{\n    var rangeKey = properties.ContainsKey(\"dataRange\") ? \"dataRange\" : \"datarange\";\n    var rangeStr = properties[rangeKey];\n    // crude column-count check: a single '!' then count columns in the range\n    var match = System.Text.RegularExpressions.Regex.Match(\n        rangeStr, @\"!?([A-Z]+)\\d+(:([A-Z]+)\\d+)?\", RegexOptions.IgnoreCase);\n    if (match.Success && (!match.Groups[3].Success ||\n        match.Groups[1].Value.Equals(match.Groups[3].Value, StringComparison.OrdinalIgnoreCase)))\n    {\n        if (!properties.ContainsKey(\"categories\"))\n            throw new InvalidOperationException(\n                \"dataRange is single-column and no categories= set; \" +\n                \"the sole column will be consumed as categories, leaving 0 series.\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try { handler.AddChart(parentPath, type, position, properties); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"dataRange resolved to 0 series\"))\n{\n    // Log and prompt user to widen dataRange or add categories=\n    Console.Error.WriteLine($\"{ex.Message} Suggested fix: add categories= or widen the range.\");\n}","preventionTips":["Always include at least two columns in dataRange (one for categories, one or more for values).","Pass categories= explicitly when you want a single column plotted as a series.","Validate the range dimensions before the add call using a regex column-count check.","Prefer data= with inline values for small datasets to avoid range-resolution ambiguity."],"tags":["excel","chart","datarange","series","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}