{"record":{"id":"75a0482f4edb6ecc","repo":"iOfficeAI/OfficeCLI","slug":"unsupported-type-75a048","errorCode":"unsupported_type","errorMessage":"Unsupported file type for merge: {ext}","messagePattern":"Unsupported file type for merge: (.+?)","errorType":"error_code","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/TemplateMerger.cs","lineNumber":183,"sourceCode":"\n        // Refuse to silently overwrite an existing output unless force is set,\n        // mirroring the `create` command's guard (CommandBuilder.Import.cs:185).\n        if (File.Exists(outputPath) && !force)\n            throw new CliException($\"Output file already exists: {outputPath}. Use --force to overwrite.\")\n            {\n                Code = \"file_exists\",\n                Suggestion = \"Add --force flag or remove the file first.\"\n            };\n\n        File.Copy(templatePath, outputPath, overwrite: true);\n\n        var ext = Path.GetExtension(outputPath).ToLowerInvariant();\n        return ext switch\n        {\n            \".docx\" => MergeDocx(outputPath, data),\n            \".xlsx\" => MergeXlsx(outputPath, data),\n            \".pptx\" => MergePptx(outputPath, data),\n            _ => throw new CliException($\"Unsupported file type for merge: {ext}\")\n            {\n                Code = \"unsupported_type\",\n                ValidValues = [\".docx\", \".xlsx\", \".pptx\"]\n            }\n        };\n    }\n\n    private static MergeResult MergeDocx(string filePath, Dictionary<string, string> data)\n    {\n        var usedKeys = new HashSet<string>();\n        int totalReplacements = 0;\n\n        // CONSISTENCY(merge-single-pass): walk every <w:t> in body + aux parts\n        // in one pass with a single-pass regex substitute. The earlier\n        // per-key handler.Set(find/replace) loop fed each substituted value\n        // back through the next iteration, so a value like \"{{name}}\" inside\n        // data[\"greeting\"] would itself be replaced — and only keys whose\n        // placeholder still survived the cascade counted as \"used\".","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/TemplateMerger.cs#L165-L201","documentation":"Thrown by Merge when the output file's extension is not one of the supported merge types. The switch handles .docx, .xlsx, and .pptx; any other extension (e.g. .pdf, .csv, .txt, missing extension) hits the default arm and throws code unsupported_type, listing ValidValues.","triggerScenarios":"Calling Merge where outputPath ends in something other than .docx/.xlsx/.pptx (case-insensitive), including a template with no extension or a .pdf target.","commonSituations":"Wrong output extension; copying a .docx template to a .pdf output; passing a directory or extensionless path.","solutions":["Use an output extension of .docx, .xlsx, or .pptx matching the template type.","Ensure the output path's extension (not the template's) is one of the supported values.","For PDF output, merge to .docx first then convert separately."],"exampleFix":"// before\nTemplateMerger.Merge(\"letter.docx\", \"letter.pdf\", data, true); // .pdf unsupported\n// after\nTemplateMerger.Merge(\"letter.docx\", \"letter.docx\", data, true);","handlingStrategy":"type-guard","validationCode":"var ext = System.IO.Path.GetExtension(outputPath).ToLowerInvariant();\nif (ext is not (\".docx\" or \".xlsx\" or \".pptx\"))\n    throw new InvalidOperationException($\"unsupported merge type: {ext}\");","typeGuard":"static bool IsSupportedMergeExt(string path)\n    => System.IO.Path.GetExtension(path).ToLowerInvariant() is \".docx\" or \".xlsx\" or \".pptx\";","tryCatchPattern":"try { result = TemplateMerger.Merge(tpl, out, data, force); }\ncatch (CliException ex) when (ex.Code == \"unsupported_type\")\n{ /* use one of: \" + string.Join(\", \", ex.ValidValues) */ }","preventionTips":["Derive the output extension from the template type.","Validate the extension in the CLI/agent layer before merging."],"tags":["template","merge","file-type","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}