iOfficeAI/OfficeCLI · error · ArgumentException

field index {roundTripFieldIdx.Value} out of range (0..{head

Error message

field index {roundTripFieldIdx.Value} out of range (0..{headers.Length - 1})

What it means

When a values= token is in the Get-readback shape (it carries an explicit cacheField index in slot 3), the parser trusts that index over the display name to make Set-after-Get robust to header renames. This throw fires when that round-trip index falls outside the current header array bounds — typically because the source range was narrowed or re-ordered between Get and Set. The message reports the allowed 0..N-1 range so the user can see how far off the cached index is.

Source

Thrown at src/officecli/Core/PivotTableHelper.Parse.cs:335

            // func[0] below. This keeps the showAs slot positionally addressable.
            if (string.IsNullOrEmpty(func)) func = "sum";

            // CONSISTENCY(aggregate-override): if aggregate=<list> was passed
            // and has an entry at this position, it wins over the colon form.
            if (aggregateOverrides != null && specIndex < aggregateOverrides.Length
                && !string.IsNullOrEmpty(aggregateOverrides[specIndex]))
                func = aggregateOverrides[specIndex];

            int fieldIdx = -1;
            // CONSISTENCY(pivot-roundtrip / R9-2): when the Get readback shape
            // gave us an explicit numeric cacheField index, prefer it over the
            // (possibly stripped) display name. This makes Set values=GetOutput
            // robust even if the source headers were renamed between Get and
            // Set, and removes any ambiguity from the prefix-strip heuristic.
            if (roundTripFieldIdx.HasValue)
            {
                if (roundTripFieldIdx.Value < 0 || roundTripFieldIdx.Value >= headers.Length)
                    throw new ArgumentException(
                        $"field index {roundTripFieldIdx.Value} out of range (0..{headers.Length - 1})");
                fieldIdx = roundTripFieldIdx.Value;
            }
            else if (int.TryParse(fieldName, out var idx))
            {
                // CONSISTENCY(strict-enums / R8-6): a numeric token is a
                // column index. Out-of-range indices used to silently drop
                // the value-field, producing an empty pivot with no error.
                // Reject up front with the available-index range so users
                // catch the typo immediately (mirrors the throw used for
                // unknown field names).
                if (idx < 0 || idx >= headers.Length)
                    throw new ArgumentException(
                        $"field index {idx} out of range (0..{headers.Length - 1})");
                fieldIdx = idx;
            }
            else
            {

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Restate the values= tokens against the new headers (drop the slot-3 index) so the name-based resolver runs instead
  2. Ensure the source range you Set against has at least as many columns as the one you Got from
  3. Re-Get the pivot from the current source to refresh the cached indices before Set

Example fix

// before (stale index 7 in a sheet that now has only 5 columns)
values="Sales:sum:7"
// after (drop the stale index, let the name resolver bind)
values="Sales:sum"
Defensive patterns

Strategy: validation

Validate before calling

// Drop stale round-trip indices when the source column count may have changed
var cleaned = valuesSpecs.Select(s => Regex.Replace(s, @":\d+$", "")); // strip trailing :<index>
// or re-Get from the current source to refresh indices

Type guard

static bool RoundTripIndexInBounds(int idx, int headerCount) =>
    idx >= 0 && idx < headerCount;

Try / catch

try { SetPivot(props); }
catch (ArgumentException ex) when (ex.Message.Contains("out of range"))
{ /* strip slot-3 indices and retry, or re-Get against current source */ }

Prevention

When it happens

Trigger: Get a pivot, then change the source range to have fewer columns, then paste the Get output back into Set; re-importing a Get dump into a workbook whose source columns were deleted; replaying a recorded spec against a template with a different column count.

Common situations: Round-trip workflows where the underlying sheet structure changed between read and write; automation that captures a pivot spec and replays it against a sibling workbook with a smaller schema.

Related errors


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