iOfficeAI/OfficeCLI · error · ArgumentException

dataRange resolved to 0 series columns: a single-column rang

Error message

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.

What it means

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.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Chart.cs:82

            // categories=A1:A4) rather than a literal list, ParseSeriesData/
            // ParseCategories leave the literal values empty (the range is only
            // emitted as a numRef/strRef formula). Real Excel — and the
            // `dataRange=` path here — also snapshot the referenced cells into
            // a numCache/strCache so the chart renders before the workbook is
            // re-evaluated (the HTML preview plots only from that cache).
            // Resolve the ranges against the worksheet now to backfill the
            // literal values, mirroring ParseDataRangeForChart.
            BackfillSeriesRangeValues(ref seriesData, ref categories, chartSheetName, properties);
        }

        if (seriesData.Count == 0)
        {
            // A supplied-but-consumed dataRange must not get the generic
            // "requires a data property" message: with a single-column range
            // and no explicit categories=, the sole column is reserved as
            // the category column, leaving zero series — say so.
            if (properties.ContainsKey("dataRange") || properties.ContainsKey("datarange"))
                throw new ArgumentException(
                    "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.");
            throw new ArgumentException("Chart requires a 'data' property. Use: data=\"Series1:1,2,3;Series2:4,5,6\" " +
                "or dataRange=\"Sheet1!A1:D5\" or series1=\"Revenue:100,200,300\"");
        }

        // Validate the chart type BEFORE any part is created: an unknown type
        // used to throw inside the builder AFTER the DrawingsPart and its
        // sheet relationship were attached, leaving an orphaned empty
        // <xdr:wsDr/> part behind on every failed attempt. Extended (cx)
        // types — funnel/treemap/… — route through ChartExBuilder below and
        // must not be run through the classic-type parser.
        if (!ChartExBuilder.IsExtendedChartType(chartType))
            ChartHelper.ParseChartType(chartType);

        // Create DrawingsPart if needed
        var drawingsPart = chartWorksheet.DrawingsPart

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Add a second column to the dataRange so at least one column survives as a values series (e.g. dataRange=Sheet1!A1:B5).
  2. 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).
  3. Switch from dataRange to the data= property with inline values: data="Series1:1,2,3".
  4. Use series1=/series2= properties for per-series literal data: series1="Revenue:100,200,300".

Example fix

// before
add /Sheet1/chart --type chart --chartType bar --dataRange Sheet1!A1:A5
// after (widen to include a values column)
add /Sheet1/chart --type chart --chartType bar --dataRange Sheet1!A1:B5
Defensive patterns

Strategy: validation

Validate before calling

// Before calling chart Add, verify the dataRange spans >= 2 columns
if (properties.ContainsKey("dataRange") || properties.ContainsKey("datarange"))
{
    var rangeKey = properties.ContainsKey("dataRange") ? "dataRange" : "datarange";
    var rangeStr = properties[rangeKey];
    // crude column-count check: a single '!' then count columns in the range
    var match = System.Text.RegularExpressions.Regex.Match(
        rangeStr, @"!?([A-Z]+)\d+(:([A-Z]+)\d+)?", RegexOptions.IgnoreCase);
    if (match.Success && (!match.Groups[3].Success ||
        match.Groups[1].Value.Equals(match.Groups[3].Value, StringComparison.OrdinalIgnoreCase)))
    {
        if (!properties.ContainsKey("categories"))
            throw new InvalidOperationException(
                "dataRange is single-column and no categories= set; " +
                "the sole column will be consumed as categories, leaving 0 series.");
    }
}

Try / catch

try { handler.AddChart(parentPath, type, position, properties); }
catch (ArgumentException ex) when (ex.Message.Contains("dataRange resolved to 0 series"))
{
    // Log and prompt user to widen dataRange or add categories=
    Console.Error.WriteLine($"{ex.Message} Suggested fix: add categories= or widen the range.");
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/ce1f61ac0260b7f4. Report an issue: GitHub.