{"record":{"id":"23181a481621f42e","repo":"iOfficeAI/OfficeCLI","slug":"unknown-command-item-command-valid-commands","errorCode":null,"errorMessage":"Unknown command: '{item.Command}'. Valid commands: get, query, set, add, remove, move, swap, view, raw, validate.{batchHint}","messagePattern":"Unknown command: '(.+?)'\\. Valid commands: get, query, set, add, remove, move, swap, view, raw, validate\\.(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/officecli/CommandBuilder.cs","lineNumber":1258,"sourceCode":"                return string.Join(\"\\n\", lines);\n            }\n            default:\n                if (string.IsNullOrEmpty(item.Command))\n                    throw new InvalidOperationException(\n                        \"Batch item missing required 'command' field. \" +\n                        \"Valid commands: get, query, set, add, remove, move, view, raw, validate. \" +\n                        \"Example: {\\\"command\\\": \\\"set\\\", \\\"path\\\": \\\"/Sheet1/A1\\\", \\\"props\\\": {\\\"value\\\": \\\"hello\\\"}}\");\n                // A \"command\" containing whitespace is almost always a whole CLI\n                // line stuffed into the verb field (e.g. \"add /slide[1] --type\n                // shape --prop ...\") — the single most common batch-item mistake.\n                // Diagnose it specifically and point at the item schema; a plain\n                // unknown verb just gets the schema pointer.\n                var batchHint = item.Command.Any(char.IsWhiteSpace)\n                    ? \" — that looks like a whole CLI line placed in \\\"command\\\". Use the bare verb only and put the\"\n                      + \" rest in sibling fields, e.g. {\\\"command\\\":\\\"add\\\",\\\"parent\\\":\\\"/slide[1]\\\",\\\"type\\\":\\\"shape\\\",\"\n                      + \"\\\"props\\\":{...}}. Run `help batch` for the item schema.\"\n                    : \" Run `help batch` for the JSON item schema.\";\n                throw new InvalidOperationException($\"Unknown command: '{item.Command}'. Valid commands: get, query, set, add, remove, move, swap, view, raw, validate.{batchHint}\");\n        }\n    }\n\n    private static Dictionary<string, string> ParsePropsArray(string[]? props)\n    {\n        var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n        foreach (var prop in props ?? Array.Empty<string>())\n        {\n            var eqIdx = prop.IndexOf('=');\n            // BUG-R40-B12: previously `eqIdx > 0` silently dropped both\n            // `--prop =value` (empty key, eqIdx==0) and `--prop key`\n            // (no equals, eqIdx==-1). Surface the empty-key form as a\n            // hard error so AI callers don't waste a turn wondering why\n            // their property had no effect.\n            if (eqIdx == 0)\n                throw new ArgumentException(\n                    $\"Invalid --prop '{prop}': key is empty. Use key=value (e.g. --prop name=Title).\");\n            if (eqIdx > 0)","sourceCodeStart":1240,"sourceCodeEnd":1276,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/CommandBuilder.cs#L1240-L1276","documentation":"Thrown in the default branch when item.Command is non-empty but matches no recognized verb. The code adds a smart 'batchHint': if the command contains whitespace it is almost certainly a whole CLI line stuffed into the verb field (e.g. 'add /slide[1] --type shape'), and the hint tells the caller to use the bare verb plus sibling fields. Otherwise the hint points at 'help batch'.","triggerScenarios":"A misspelled verb (e.g. 'delete' instead of 'remove', 'insert' instead of 'add'). A whole CLI line placed in 'command' (whitespace detected). A verb from an older/newer version not in this build.","commonSituations":"An agent trained on the single-command CLI pastes 'add /slide[1] --type shape --prop ...' into the batch command field. A caller uses a synonym the tool never supported.","solutions":["Use only a documented bare verb as 'command': get, query, set, add, remove, move, swap, view, raw, validate, add-part, raw-set, import.","If your 'command' contains spaces, split it: the verb goes in 'command', the target in 'path'/'parent', options in sibling fields and 'props'.","Run 'help batch' for the canonical JSON item schema."],"exampleFix":"// before\n{\"command\":\"add /slide[1] --type shape --prop text=Hi\"}\n// after\n{\"command\":\"add\",\"parent\":\"/slide[1]\",\"type\":\"shape\",\"props\":{\"text\":\"Hi\"}}","handlingStrategy":"validation","validationCode":"if (!string.IsNullOrEmpty(item.Command) && item.Command.Any(char.IsWhiteSpace))\n    throw new InvalidOperationException(\n        \"'command' must be a bare verb; move the rest into sibling fields. \" +\n        \"e.g. {\\\"command\\\":\\\"add\\\",\\\"parent\\\":\\\"/slide[1]\\\",\\\"type\\\":\\\"shape\\\",\\\"props\\\":{...}}\");","typeGuard":"static bool IsBareVerb(string? c) =>\n    !string.IsNullOrEmpty(c) && !c.Any(char.IsWhiteSpace) && ValidBatchCommands.Contains(c);","tryCatchPattern":"try { result = Dispatch(item); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Unknown command\"))\n{ /* ex.Message carries batchHint — surface it to the caller */ }","preventionTips":["Never paste a whole CLI line into 'command' — split verb vs. operands vs. props.","Keep the canonical verb set in one place and validate membership.","Surface the tool's 'help batch' output to AI callers as schema context."],"tags":["batch","unknown-command","dispatch","schema"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}