iOfficeAI/OfficeCLI · error · ArgumentException

Invalid sparkline 'location': '{spkCell}'. Expected a cell r

Error message

Invalid sparkline 'location': '{spkCell}'. Expected a cell reference like F1 (or a range like F1:F5).

What it means

Thrown when the resolved sparkline location, after sheet-prefix stripping (NormalizeSparklineSqref), is empty or does not match the cell-reference regex `^\$?[A-Za-z]{1,3}\$?\d+(:\$?[A-Za-z]{1,3}\$?\d+)?$`. This guard exists because a non-cell location (e.g. `XYZ`, empty, or a label) previously wrote a semantically dead xm:sqref anchor that Excel silently dropped, leaving the sparkline invisible. Unlike 546 (which fires when location is entirely absent), this fires when a location IS supplied but is not a valid cell reference.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs:993

            ?? properties.GetValueOrDefault("cell")
            ?? spkPathTail
            ?? throw new ArgumentException("Sparkline requires 'location' (or 'cell') property (e.g. F1)");
        var spkRange = properties.GetValueOrDefault("dataRange")
            ?? properties.GetValueOrDefault("datarange")
            ?? properties.GetValueOrDefault("range")
            ?? properties.GetValueOrDefault("data")
            ?? throw new ArgumentException("Sparkline requires 'dataRange' (or 'range'/'data') property (e.g. A1:E1)");

        // OOXML xm:sqref is ST_Sqref (bare cell address, no sheet prefix —
        // sheet is implied by the parent worksheet). Excel silently drops the
        // entire <extLst> on load if sqref carries a sheet prefix.
        spkCell = NormalizeSparklineSqref(spkCell, spkSheetName);
        // A location that is not a real cell reference ("XYZ", empty) wrote a
        // semantically dead <xne:sqref> anchor with no warning; validate the
        // final sqref like every other cell-ref input.
        if (string.IsNullOrWhiteSpace(spkCell)
            || !Regex.IsMatch(spkCell, @"^\$?[A-Za-z]{1,3}\$?\d+(:\$?[A-Za-z]{1,3}\$?\d+)?$"))
            throw new ArgumentException(
                $"Invalid sparkline 'location': '{spkCell}'. Expected a cell reference like F1 (or a range like F1:F5).");
        ParseCellReference(spkCell.Replace("$", "").Split(':')[0]);

        // Determine sparkline type
        // bt-2: reject invalid types (e.g. "bar") instead of silently mapping
        // to Line. Sparkline OOXML has exactly three types: line/column/stacked
        // (winloss is an alias for stacked).
        var spkTypeStr = properties.GetValueOrDefault("type", "line").ToLowerInvariant();
        var spkType = spkTypeStr switch
        {
            "line" => X14.SparklineTypeValues.Line,
            "column" => X14.SparklineTypeValues.Column,
            "stacked" or "winloss" or "win-loss" => X14.SparklineTypeValues.Stacked,
            _ => throw new ArgumentException(
                $"Invalid sparkline type: '{spkTypeStr}'. Valid values: line, column, stacked (alias: winloss/win-loss).")
        };

        // Build the SparklineGroup

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Supply a concrete cell address for location, e.g. `F1`, or a range `F1:F5` (optional $ signs are tolerated).
  2. Do not include the sheet prefix in location (it is implied by the parent path); NormalizeSparklineSqref strips it but leaving it bare avoids ambiguity.

Example fix

// before
add ./book.xlsx /Sheet1 sparkline --prop location=Total --prop dataRange=A1:E1
// after
add ./book.xlsx /Sheet1 sparkline --prop location=F1 --prop dataRange=A1:E1
Defensive patterns

Strategy: validation

Validate before calling

// Validate the resolved location with the handler's own cell-ref grammar.
var cellRe = @"^\$?[A-Za-z]{1,3}\$?\d+(:\$?[A-Za-z]{1,3}\$?\d+)?$";
if (string.IsNullOrWhiteSpace(hostCell) || !Regex.IsMatch(hostCell, cellRe))
    throw new InvalidOperationException($"Sparkline location '{hostCell}' is not a cell reference");

Type guard

static bool IsValidSparklineCell(string? s)
    => !string.IsNullOrWhiteSpace(s)
    && System.Text.RegularExpressions.Regex.IsMatch(s,
        @"^\$?[A-Za-z]{1,3}\$?\d+(:\$?[A-Za-z]{1,3}\$?\d+)?$");

Try / catch

try { handler.AddSparkline(...); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid sparkline 'location'"))
{ /* reprompt: need a real cell like F1, not a label */ }

Prevention

When it happens

Trigger: Passing `--prop location=Total` (a label, not a cell), `--prop location=` (empty after trim), or a path tail that looks like a cell but isn't (`/Sheet1/ABC`). Also when NormalizeSparklineSqref strips a sheet prefix and leaves nothing valid.

Common situations: Pointing the sparkline at a named cell label instead of its address; location derived from a user input field that isn't validated; copy-paste introducing a stray prefix.

Related errors


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