{"record":{"id":"3a466ff9bf08e098","repo":"iOfficeAI/OfficeCLI","slug":"unsupported-property","errorCode":"unsupported_property","errorMessage":"{string.Join(\"\\n\", parts)}","messagePattern":"\\{string\\.Join\\(\"\\\\n\", parts\\)\\}","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/CommandBuilder.cs","lineNumber":1047,"sourceCode":"                        string? batchScope = handler switch\n                        {\n                            OfficeCli.Handlers.ExcelHandler => \"excel\",\n                            OfficeCli.Handlers.WordHandler => \"word\",\n                            OfficeCli.Handlers.PowerPointHandler => \"pptx\",\n                            _ => null,\n                        };\n                        parts.Add(FormatUnsupported(unsupported, batchScope));\n                    }\n                    // Mirror standalone `set`'s allFailed semantics: if every\n                    // requested property was rejected (nothing applied), the\n                    // step is a failure, not a successful no-op. Without\n                    // this, batch swallowed unsupported_property into an inner\n                    // success=true while the same set issued via the\n                    // standalone set command returned success=false exit 2.\n                    // Per-step verdict flips to false; outer batch envelope\n                    // still rides on the existing partial-success rule.\n                    if (applied.Count == 0)\n                        throw new CliException(string.Join(\"\\n\", parts)) { Code = \"unsupported_property\" };\n                }\n                return string.Join(\"\\n\", parts);\n            }\n            case \"add\":\n            {\n                var parentPath = item.Parent ?? item.Path;\n                if (string.IsNullOrEmpty(parentPath))\n                    throw new ArgumentException(\"'add' command requires 'parent' field. Example: {\\\"command\\\": \\\"add\\\", \\\"parent\\\": \\\"/slide[1]\\\", \\\"type\\\": \\\"shape\\\", \\\"props\\\": {\\\"text\\\": \\\"Hello\\\"}}\");\n                if (string.IsNullOrEmpty(item.Type) && string.IsNullOrEmpty(item.From))\n                    throw new ArgumentException(\"'add' command requires 'type' or 'from' field. Example: {\\\"command\\\": \\\"add\\\", \\\"parent\\\": \\\"/\\\", \\\"type\\\": \\\"slide\\\"}\");\n                InsertPosition? pos = null;\n                if (item.Index.HasValue) pos = InsertPosition.AtIndex(item.Index.Value);\n                else if (!string.IsNullOrEmpty(item.After)) pos = InsertPosition.AfterElement(item.After);\n                else if (!string.IsNullOrEmpty(item.Before)) pos = InsertPosition.BeforeElement(item.Before);\n\n                if (!string.IsNullOrEmpty(item.From))\n                {\n                    var resultPath = handler.CopyFrom(item.From, parentPath, pos);","sourceCodeStart":1029,"sourceCodeEnd":1065,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/CommandBuilder.cs#L1029-L1065","documentation":"Thrown by ExecuteBatchItem for a batch \"set\" step where the handler rejected EVERY requested property (applied.Count == 0). The per-step verdict flips to failure with Code=\"unsupported_property\" to mirror the standalone set's allFailed semantics (exit 2). The message is the joined \"parts\": any auto-correct note plus the formatted unsupported-property hints (which typically list valid props). Partial application (some applied, some rejected) does NOT throw.","triggerScenarios":"{\"command\":\"set\",\"path\":\"/sheet[1]/row[1]\",\"props\":{\"colour\":\"red\"}} where \"colour\" is not a unique distance-1 typo and nothing applies; setting Excel-only props on a path the handler does not support; version-specific prop names.","commonSituations":"Wrong prop vocabulary for the document type (e.g. PPT props on an Excel path); typos beyond autocorrect range; deprecated/renamed props after an upgrade; copy of a step across handlers without adapting prop names.","solutions":["Read the message: it includes 'valid props:' for the scope — replace each bad key with a listed one.","Fix typos so they are within autocorrect range (Levenshtein distance 1) or exact.","If you genuinely need an unsupported prop, use raw-set as the documented escape hatch.","Confirm the props match the handler type for the target path (excel/word/pptx)."],"exampleFix":"// before\n{\"command\":\"set\",\"path\":\"/sheet[1]/row[1]\",\"props\":{\"colour\":\"red\"}}\n// after\n{\"command\":\"set\",\"path\":\"/sheet[1]/row[1]\",\"props\":{\"color\":\"red\"}}","handlingStrategy":"try-catch","validationCode":"// Validate prop names against the handler's supported set before submitting.\nvar supported = handler.SupportedProps(path);  // pseudocode\nvar bad = props.Keys.Except(supported, StringComparer.OrdinalIgnoreCase).ToList();\nif (bad.Count == props.Count) /* all will be rejected — fix or raw-set */","typeGuard":null,"tryCatchPattern":"try { ExecuteBatchItem(handler, item, json); }\ncatch (CliException ex) when (ex.Code == \"unsupported_property\")\n{ /* parse 'valid props:' hint, fix keys, retry or raw-set */ }","preventionTips":["Read the 'valid props:' hint in the message before retrying.","Keep prop names within autocorrect range (Levenshtein 1) or exact.","Use raw-set only as a deliberate escape hatch for genuinely unsupported props.","Match prop vocabulary to the handler type for the target path."],"tags":["batch","set","unsupported-property","validation","officecli"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}