iOfficeAI/OfficeCLI · error · CliException

unsupported_type

unsupported_type

Error message

Unsupported file type for merge: {ext}

What it means

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.

Source

Thrown at src/officecli/Core/TemplateMerger.cs:183

        // Refuse to silently overwrite an existing output unless force is set,
        // mirroring the `create` command's guard (CommandBuilder.Import.cs:185).
        if (File.Exists(outputPath) && !force)
            throw new CliException($"Output file already exists: {outputPath}. Use --force to overwrite.")
            {
                Code = "file_exists",
                Suggestion = "Add --force flag or remove the file first."
            };

        File.Copy(templatePath, outputPath, overwrite: true);

        var ext = Path.GetExtension(outputPath).ToLowerInvariant();
        return ext switch
        {
            ".docx" => MergeDocx(outputPath, data),
            ".xlsx" => MergeXlsx(outputPath, data),
            ".pptx" => MergePptx(outputPath, data),
            _ => throw new CliException($"Unsupported file type for merge: {ext}")
            {
                Code = "unsupported_type",
                ValidValues = [".docx", ".xlsx", ".pptx"]
            }
        };
    }

    private static MergeResult MergeDocx(string filePath, Dictionary<string, string> data)
    {
        var usedKeys = new HashSet<string>();
        int totalReplacements = 0;

        // CONSISTENCY(merge-single-pass): walk every <w:t> in body + aux parts
        // in one pass with a single-pass regex substitute. The earlier
        // per-key handler.Set(find/replace) loop fed each substituted value
        // back through the next iteration, so a value like "{{name}}" inside
        // data["greeting"] would itself be replaced — and only keys whose
        // placeholder still survived the cascade counted as "used".

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use an output extension of .docx, .xlsx, or .pptx matching the template type.
  2. Ensure the output path's extension (not the template's) is one of the supported values.
  3. For PDF output, merge to .docx first then convert separately.

Example fix

// before
TemplateMerger.Merge("letter.docx", "letter.pdf", data, true); // .pdf unsupported
// after
TemplateMerger.Merge("letter.docx", "letter.docx", data, true);
Defensive patterns

Strategy: type-guard

Validate before calling

var ext = System.IO.Path.GetExtension(outputPath).ToLowerInvariant();
if (ext is not (".docx" or ".xlsx" or ".pptx"))
    throw new InvalidOperationException($"unsupported merge type: {ext}");

Type guard

static bool IsSupportedMergeExt(string path)
    => System.IO.Path.GetExtension(path).ToLowerInvariant() is ".docx" or ".xlsx" or ".pptx";

Try / catch

try { result = TemplateMerger.Merge(tpl, out, data, force); }
catch (CliException ex) when (ex.Code == "unsupported_type")
{ /* use one of: " + string.Join(", ", ex.ValidValues) */ }

Prevention

When it happens

Trigger: Calling Merge where outputPath ends in something other than .docx/.xlsx/.pptx (case-insensitive), including a template with no extension or a .pdf target.

Common situations: Wrong output extension; copying a .docx template to a .pdf output; passing a directory or extensionless path.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/75a0482f4edb6ecc. Report an issue: GitHub.