Stirling-Tools/Stirling-PDF · error · Error

Unsupported conversion format

Error message

Unsupported conversion format

What it means

Thrown by the convert processor when `getEndpointUrl(fromExtension, toExtension)` returns a falsy value — i.e. the requested source→target conversion pair has no mapped backend endpoint. The convert tool routes each pair to a specific REST endpoint; an unmapped pair means the backend does not support that conversion.

Source

Thrown at frontend/editor/src/core/hooks/tools/convert/useConvertOperation.ts:254

  const fallbackFilename = `${originalName}.${targetExtension}`;

  return createFileFromApiResponse(responseData, headers, fallbackFilename);
};

// Static processor that can be used by both the hook and automation executor
export const convertProcessor = async (
  parameters: ConvertParameters,
  selectedFiles: File[],
): Promise<CustomProcessorResult> => {
  const processedFiles: File[] = [];

  // Map PDF/X to use PDF/A endpoint
  const actualToExtension =
    parameters.toExtension === "pdfx" ? "pdfa" : parameters.toExtension;
  const endpoint = getEndpointUrl(parameters.fromExtension, actualToExtension);

  if (!endpoint) {
    throw new Error("Unsupported conversion format");
  }

  // Convert-specific routing logic: decide batch vs individual processing
  // For PDF/X, we want to treat it similar to PDF/A (separate processing)
  const isSeparateProcessing = shouldProcessFilesSeparately(selectedFiles, {
    ...parameters,
    toExtension: actualToExtension, // Use the mapped extension for decision logic
  });

  if (isSeparateProcessing) {
    // Individual processing for complex cases (PDF→image, smart detection, etc.)
    for (const file of selectedFiles) {
      try {
        const formData = buildConvertFormData(parameters, [file]);
        const response = await apiClient.post(endpoint, formData, {
          responseType: "blob",
        });

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Normalize and lowercase fromExtension/toExtension before lookup, and strip leading dots.
  2. Extend getEndpointUrl's mapping to cover the missing pair, or restrict the picker to supported pairs.
  3. Surface the unsupported pair to the user ('Conversion from X to Y is not supported') instead of a generic message.
  4. Add a unit test over the full supported extension matrix so regressions in the map are caught.

Example fix

// before
const actualToExtension = parameters.toExtension === "pdfx" ? "pdfa" : parameters.toExtension;
const endpoint = getEndpointUrl(parameters.fromExtension, actualToExtension);
if (!endpoint) throw new Error("Unsupported conversion format");

// after — normalize and name the unsupported pair
const from = parameters.fromExtension.toLowerCase().replace(/^\./, "");
const to = (parameters.toExtension === "pdfx" ? "pdfa" : parameters.toExtension).toLowerCase().replace(/^\./, "");
const endpoint = getEndpointUrl(from, to);
if (!endpoint) throw new Error(`Unsupported conversion format: ${from} → ${to}`);
Defensive patterns

Strategy: validation

Validate before calling

// Normalize and check the conversion pair is supported before posting
const from = String(parameters.fromExtension).toLowerCase().replace(/^\./, "");
const to = String(parameters.toExtension).toLowerCase().replace(/^\./, "");
if (!getEndpointUrl(from, to === "pdfx" ? "pdfa" : to)) {
  // do not call convertProcessor; show 'X to Y not supported'
}

Type guard

function isSupportedPair(from: string, to: string): boolean {
  return !!getEndpointUrl(from.toLowerCase().replace(/^\./, ""), to.toLowerCase().replace(/^\./, ""));
}

Try / catch

try {
  await convertProcessor(parameters, selectedFiles);
} catch (e) {
  if (e instanceof Error && e.message === "Unsupported conversion format") {
    toast.error(`Conversion ${parameters.fromExtension} → ${parameters.toExtension} is not supported.`);
  } else throw e;
}

Prevention

When it happens

Trigger: User (or automation step) requested a from/to combination the frontend converter does not know about (e.g. a brand-new extension not yet wired into getEndpointUrl); pdfx is mapped to pdfa but a different unsupported alias slipped through; file extension detection produced an unexpected value (uppercase, leading dot, unknown format).

Common situations: New file format added to the picker but not to the endpoint map; extension normalization bug (case sensitivity, trailing whitespace); user-supplied/automation-provided extension that bypassed the dropdown.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/dfebb7c15e0cd6e3. Report an issue: GitHub.