{"record":{"id":"5c5617d561c06d34","repo":"iOfficeAI/OfficeCLI","slug":"add-part-command-requires-type-field-supporte","errorCode":null,"errorMessage":"'add-part' command requires 'type' field. Supported (pptx): chart, smartart, video, audio, model3d, ole, image, hyperlink, theme.","messagePattern":"'add-part' command requires 'type' field\\. Supported \\(pptx\\): chart, smartart, video, audio, model3d, ole, image, hyperlink, theme\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/CommandBuilder.cs","lineNumber":1225,"sourceCode":"            {\n                if (string.IsNullOrEmpty(item.Part))\n                    throw new ArgumentException(\"'raw' command requires 'part' field. Example: {\\\"command\\\": \\\"raw\\\", \\\"part\\\": \\\"/document\\\"} (docx), {\\\"command\\\": \\\"raw\\\", \\\"part\\\": \\\"/presentation\\\"} (pptx), {\\\"command\\\": \\\"raw\\\", \\\"part\\\": \\\"/sheet[1]\\\"} (xlsx)\");\n                return handler.Raw(item.Part, null, null, null);\n            }\n            case \"raw-set\":\n            {\n                var partPath = item.Part ?? \"/document\";\n                var xpath = item.Xpath ?? \"\";\n                var action = item.Action ?? \"\";\n                handler.RawSet(partPath, xpath, action, item.Xml);\n                return $\"raw-set {action} applied\";\n            }\n            case \"add-part\":\n            {\n                if (string.IsNullOrEmpty(item.Parent))\n                    throw new ArgumentException(\"'add-part' command requires 'parent' field. Example: {\\\"command\\\": \\\"add-part\\\", \\\"parent\\\": \\\"/slide[1]\\\", \\\"type\\\": \\\"smartart\\\", \\\"props\\\": {\\\"data\\\": \\\"rId2\\\"}}\");\n                if (string.IsNullOrEmpty(item.Type))\n                    throw new ArgumentException(\"'add-part' command requires 'type' field. Supported (pptx): chart, smartart, video, audio, model3d, ole, image, hyperlink, theme.\");\n                var (relId, partOut) = handler.AddPart(item.Parent, item.Type, props);\n                return $\"Created {item.Type} part: relId={relId} path={partOut}\";\n            }\n            case \"validate\":\n            {\n                var errors = handler.Validate();\n                if (errors.Count == 0) return \"Validation passed: no errors found.\";\n                var lines = new List<string> { $\"Found {errors.Count} validation error(s):\" };\n                foreach (var err in errors)\n                {\n                    lines.Add($\"  [{err.ErrorType}] {err.Description}\");\n                    if (err.Path != null) lines.Add($\"    Path: {err.Path}\");\n                    if (err.Part != null) lines.Add($\"    Part: {err.Part}\");\n                }\n                return string.Join(\"\\n\", lines);\n            }\n            default:\n                if (string.IsNullOrEmpty(item.Command))","sourceCodeStart":1207,"sourceCodeEnd":1243,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/CommandBuilder.cs#L1207-L1243","documentation":"Thrown by the batch 'add-part' command when item.Type is null or empty (after parent has already been validated). The type selects which kind of package part to create; without it the handler cannot dispatch. The message enumerates the pptx-supported types so the caller can pick the right one.","triggerScenarios":"An add-part item with 'parent' set but 'type' omitted or empty. A caller that puts the kind under 'props.kind' instead of the top-level 'type' field.","commonSituations":"An agent emits the parent (copied from a remove/add template) and a props blob but forgets the verb-specific 'type'. A caller uses a synonym like 'kind' or 'category'.","solutions":["Add a 'type' field with one of: chart, smartart, video, audio, model3d, ole, image, hyperlink, theme (pptx).","Make sure 'type' is a top-level item field, not nested inside 'props'.","Check the per-document-type supported list in the message — not all types exist for every format."],"exampleFix":"// before\n{\"command\":\"add-part\",\"parent\":\"/slide[1]\",\"props\":{\"data\":\"rId2\"}}\n// after\n{\"command\":\"add-part\",\"parent\":\"/slide[1]\",\"type\":\"smartart\",\"props\":{\"data\":\"rId2\"}}","handlingStrategy":"validation","validationCode":"var pptxPartTypes = new[] { \"chart\",\"smartart\",\"video\",\"audio\",\"model3d\",\"ole\",\"image\",\"hyperlink\",\"theme\" };\nif (string.IsNullOrEmpty(item.Type))\n    throw new ArgumentException(\"'add-part' requires 'type' from: \" + string.Join(\", \", pptxPartTypes));","typeGuard":"static bool HasAddPartType(BatchItem i) => !string.IsNullOrEmpty(i.Type);","tryCatchPattern":"try { (relId, part) = Dispatch(item); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"'add-part' command requires 'type'\"))\n{ /* pick a supported type and retry */ }","preventionTips":["Keep a per-document-type list of supported part types and validate against it.","Put 'type' at the item top level, not inside 'props'.","Use the exact token from the message (no synonyms)."],"tags":["batch","add-part","missing-field","type"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}