iOfficeAI/OfficeCLI · error · ArgumentException
--prop shift={shiftVal} not valid for add cell. Use 'right'
Error message
--prop shift={shiftVal} not valid for add cell. Use 'right' or 'down'. What it means
The `shift` property on Add cell mimics Excel UI's 'Insert Cells > Shift cells right / down', pushing existing cells in the same row (right) or column (down) by 1 before materializing the new cell. Only the literal tokens 'right' and 'down' (case-insensitive) are accepted. Any other value is rejected before the shift so no cells are moved on a failed call.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs:452
if (rowIndexFromPath.HasValue)
{
var refRowMatch = Regex.Match(cellRef, @"^([A-Z]+)(\d+)$", RegexOptions.IgnoreCase);
if (refRowMatch.Success && uint.Parse(refRowMatch.Groups[2].Value) != rowIndexFromPath.Value)
Console.Error.WriteLine(
$"warning: path row[{rowIndexFromPath.Value}] does not match cell ref '{cellRef}' row; using ref's row.");
}
// --prop shift=right|down: before materializing the new cell, push
// existing cells in the same row (right) or column (down) by 1.
// Mirrors Excel UI's "Insert Cells > Shift cells right / down".
// Same scope cap as RemoveCellWithShift: only intra-row/col cellRefs
// are rewritten — formulas, mergeCells, CF/DV/hyperlinks/tables that
// span the affected row/col are NOT adjusted. For full row/col insert
// with all relations, use add --type row / --type col.
if (properties.TryGetValue("shift", out var shiftVal) && !string.IsNullOrEmpty(shiftVal))
{
var shiftDir = shiftVal.ToLowerInvariant();
if (shiftDir is not ("right" or "down"))
throw new ArgumentException(
$"--prop shift={shiftVal} not valid for add cell. Use 'right' or 'down'.");
var (shiftCol, shiftRow) = ParseCellReference(cellRef);
var shiftColIdx = ColumnNameToIndex(shiftCol);
if (shiftDir == "right")
ShiftCellsRightInRow(cellSheetData, (uint)shiftRow, shiftColIdx);
else
ShiftCellsDownInColumn(cellSheetData, shiftCol, shiftRow);
}
// Atomicity: validate a type=boolean value BEFORE FindOrCreateCell
// appends the cell to the sheet. A throw AFTER the cell is created
// used to leave a corrupt <c t="b"><v>garbage</v></c> persisted on
// disk (real Excel then refuses the file, 0x800A03EC) even though the
// Add reported an error. The later in-switch check stays as a
// defense-in-depth guard.
{
var upfrontType = properties.GetValueOrDefault("type")?.ToLowerInvariant();
var upfrontValue = (properties.GetValueOrDefault("value")View on GitHub (pinned to 1ced45e900)
Solutions
- Use exactly 'right' (shift cells in the same row to the right) or 'down' (shift cells in the same column down).
- Trim and normalize the value to lowercase before passing it as the shift prop.
- For full row/column insertion with all relations, use add --type row / add --type col instead of cell shift.
Example fix
// before
handler.Add("/Sheet1/B2", "cell", null, new() { ["value"] = "x", ["shift"] = "left" });
// after
handler.Add("/Sheet1/B2", "cell", null, new() { ["value"] = "x", ["shift"] = "right" }); Defensive patterns
Strategy: validation
Validate before calling
if (props.TryGetValue("shift", out var s))
{
var d = s.Trim().ToLowerInvariant();
if (d != "right" && d != "down")
throw new ArgumentException("shift must be 'right' or 'down'");
props["shift"] = d;
}
h.Add(parentPath, "cell", pos, props); Type guard
static bool IsValidShift(string s) => s.Trim().ToLowerInvariant() is "right" or "down";
Try / catch
try { h.Add(parentPath, "cell", pos, props); }
catch (ArgumentException ex) when (ex.Message.Contains("not valid for add cell"))
{ /* correct to right/down */ } Prevention
- Trim and lowercase the shift value before passing.
- Remember cell-level insert only supports right/down; use add row/col for full structural insert.
- Do not expect left/up — those are Remove operations.
When it happens
Trigger: Add("/Sheet1/A1","cell",pos,{["shift"]="left"}); shift="up"; shift="horizontal"; shift="RIGHT " with trailing space after ToLowerInvariant is applied but the match is exact so 'right ' (with space) fails.
Common situations: Expecting four-directional shift (Excel insert only offers right/down for a single-cell insert; left/up are Remove operations); passing a localized word instead of the English token; trailing whitespace from a config file.
Related errors
- Unrecognized cell parent path segment '{cellSegments[1]}'. E
- Invalid cell reference: '{cellRef}'
- Cannot store '{properties.GetValueOrDefault("value") ?? prop
- Literal braces '{...}' around a formula create an Excel-reje
- Invalid cell 'type' value '{cellType}'. Valid types: string,
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/cee7ecff96d466de.
Report an issue: GitHub.