{"record":{"id":"20ff0c355dc23bc6","repo":"iOfficeAI/OfficeCLI","slug":"invalid-value-20ff0c","errorCode":"invalid_value","errorMessage":"shift is supported only for Excel cell paths (e.g. /Sheet1/B5).","messagePattern":"shift is supported only for Excel cell paths \\(e\\.g\\. /Sheet1/B5\\)\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/CommandBuilder.cs","lineNumber":737,"sourceCode":"        {\n            Console.Error.WriteLine($\"Error: {OfficeCli.Core.MsysPathHint.AugmentMessage(rendered.Message)}\");\n        }\n    }\n\n    /// <summary>\n    /// Remove a path, honouring a prop-carried <c>shift</c> (Excel cell delete\n    /// with shift=left|up). The CLI exposes shift via a dedicated --shift option\n    /// that routes to <c>RemoveCellWithShift</c>; the MCP single-command and\n    /// batch surfaces carry it inside props, so without this they silently\n    /// dropped it (plain <c>Remove</c> ignores props[\"shift\"]). Shared so all\n    /// three surfaces behave identically. Returns the handler's warning (or null).\n    /// </summary>\n    internal static string? RemoveWithShiftSupport(OfficeCli.Core.IDocumentHandler handler, string path, Dictionary<string, string>? props)\n    {\n        if (props != null && props.TryGetValue(\"shift\", out var shift) && !string.IsNullOrEmpty(shift))\n        {\n            if (handler is not OfficeCli.Handlers.ExcelHandler xl)\n                throw new OfficeCli.Core.CliException(\"shift is supported only for Excel cell paths (e.g. /Sheet1/B5).\")\n                    { Code = \"invalid_value\" };\n            return xl.RemoveCellWithShift(path, shift);\n        }\n        return handler.Remove(path, props);\n    }\n\n    /// <summary>Categorised result of <see cref=\"ApplySetWithCorrection\"/>.</summary>\n    internal sealed record SetApplyOutcome(\n        List<KeyValuePair<string, string>> Applied,\n        List<string> Unsupported,\n        List<(string Original, string Corrected, string Value)> AutoCorrected);\n\n    /// <summary>\n    /// Apply a set's props, auto-correct any unsupported key that is a unique\n    /// Levenshtein-distance-1 typo of a real prop (e.g. colot→color), and\n    /// categorise the result into applied / still-unsupported / auto-corrected.\n    ///\n    /// This is the ONE shared core behind every set surface — the non-resident","sourceCodeStart":719,"sourceCodeEnd":755,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/CommandBuilder.cs#L719-L755","documentation":"Thrown by RemoveWithShiftSupport when the props dictionary carries a non-empty \"shift\" key but the active document handler is not the ExcelHandler. shift=left|up only has meaning for Excel cell deletion (it routes to RemoveCellWithShift); Word and PowerPoint ignore it under plain Remove, so passing it on those types is treated as a caller mistake rather than silently dropped. CliException with Code=\"invalid_value\".","triggerScenarios":"A batch or MCP remove step with a shift prop on a non-Excel file: {\"command\":\"remove\",\"path\":\"/slide[1]\",\"props\":{\"shift\":\"left\"}}; replaying an Excel dump/replay against a .docx; a generic remove helper that always attaches shift.","commonSituations":"A reusable batch template applied across file types; an MCP single-command that forwards shift unconditionally; copy of an Excel-oriented step into a Word/PPT workflow without stripping shift.","solutions":["Drop the shift prop for non-Excel files; only Word/PowerPoint paths reach this branch.","Only emit shift when the document is .xlsx and the path targets a cell (e.g. /Sheet1/B5).","Type-check the handler/document before constructing the props dict.","In a cross-type batch driver, branch on file extension and omit shift for non-xlsx."],"exampleFix":"// before\n{\"command\":\"remove\",\"path\":\"/slide[1]\",\"props\":{\"shift\":\"left\"}}\n// after\n{\"command\":\"remove\",\"path\":\"/slide[1]\"}","handlingStrategy":"validation","validationCode":"// Only attach shift for Excel cell paths.\nvar props = new Dictionary<string,string>();\nif (handler is ExcelHandler && IsCellPath(path))\n    props[\"shift\"] = shiftDir;   // \"left\" | \"up\"\n// otherwise omit shift entirely","typeGuard":"static bool IsExcelCellPath(IDocumentHandler h, string path)\n    => h is ExcelHandler && path.StartsWith(\"/\") && Regex.IsMatch(path, @\"^/[^/]+/[A-Z]+[0-9]+\");","tryCatchPattern":null,"preventionTips":["Branch on handler type before constructing props.","Only emit shift for .xlsx cell paths like /Sheet1/B5.","Strip shift in cross-type batch drivers for non-Excel files."],"tags":["excel","remove","shift","validation","invalid-value","officecli"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}