{"record":{"id":"cee7ecff96d466de","repo":"iOfficeAI/OfficeCLI","slug":"prop-shift-shiftval-not-valid-for-add-cell-us","errorCode":null,"errorMessage":"--prop shift={shiftVal} not valid for add cell. Use 'right' or 'down'.","messagePattern":"--prop shift=(.+?) not valid for add cell\\. Use 'right' or 'down'\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":452,"sourceCode":"        if (rowIndexFromPath.HasValue)\n        {\n            var refRowMatch = Regex.Match(cellRef, @\"^([A-Z]+)(\\d+)$\", RegexOptions.IgnoreCase);\n            if (refRowMatch.Success && uint.Parse(refRowMatch.Groups[2].Value) != rowIndexFromPath.Value)\n                Console.Error.WriteLine(\n                    $\"warning: path row[{rowIndexFromPath.Value}] does not match cell ref '{cellRef}' row; using ref's row.\");\n        }\n        // --prop shift=right|down: before materializing the new cell, push\n        // existing cells in the same row (right) or column (down) by 1.\n        // Mirrors Excel UI's \"Insert Cells > Shift cells right / down\".\n        // Same scope cap as RemoveCellWithShift: only intra-row/col cellRefs\n        // are rewritten — formulas, mergeCells, CF/DV/hyperlinks/tables that\n        // span the affected row/col are NOT adjusted. For full row/col insert\n        // with all relations, use add --type row / --type col.\n        if (properties.TryGetValue(\"shift\", out var shiftVal) && !string.IsNullOrEmpty(shiftVal))\n        {\n            var shiftDir = shiftVal.ToLowerInvariant();\n            if (shiftDir is not (\"right\" or \"down\"))\n                throw new ArgumentException(\n                    $\"--prop shift={shiftVal} not valid for add cell. Use 'right' or 'down'.\");\n            var (shiftCol, shiftRow) = ParseCellReference(cellRef);\n            var shiftColIdx = ColumnNameToIndex(shiftCol);\n            if (shiftDir == \"right\")\n                ShiftCellsRightInRow(cellSheetData, (uint)shiftRow, shiftColIdx);\n            else\n                ShiftCellsDownInColumn(cellSheetData, shiftCol, shiftRow);\n        }\n\n        // Atomicity: validate a type=boolean value BEFORE FindOrCreateCell\n        // appends the cell to the sheet. A throw AFTER the cell is created\n        // used to leave a corrupt <c t=\"b\"><v>garbage</v></c> persisted on\n        // disk (real Excel then refuses the file, 0x800A03EC) even though the\n        // Add reported an error. The later in-switch check stays as a\n        // defense-in-depth guard.\n        {\n            var upfrontType = properties.GetValueOrDefault(\"type\")?.ToLowerInvariant();\n            var upfrontValue = (properties.GetValueOrDefault(\"value\")","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L434-L470","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nhandler.Add(\"/Sheet1/B2\", \"cell\", null, new() { [\"value\"] = \"x\", [\"shift\"] = \"left\" });\n// after\nhandler.Add(\"/Sheet1/B2\", \"cell\", null, new() { [\"value\"] = \"x\", [\"shift\"] = \"right\" });","handlingStrategy":"validation","validationCode":"if (props.TryGetValue(\"shift\", out var s))\n{\n    var d = s.Trim().ToLowerInvariant();\n    if (d != \"right\" && d != \"down\")\n        throw new ArgumentException(\"shift must be 'right' or 'down'\");\n    props[\"shift\"] = d;\n}\nh.Add(parentPath, \"cell\", pos, props);","typeGuard":"static bool IsValidShift(string s) => s.Trim().ToLowerInvariant() is \"right\" or \"down\";","tryCatchPattern":"try { h.Add(parentPath, \"cell\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"not valid for add cell\"))\n{ /* correct to right/down */ }","preventionTips":["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."],"tags":["excel","xlsx","cell","shift","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}