danny-avila/LibreChat · error · Error

Failed to convert HEIC image to JPEG

Error message

Failed to convert HEIC image to JPEG

What it means

Thrown by convertHEICToJPEG in client/src/utils/heicConverter.ts when the wrapped conversion pipeline rejects. The catch swallows the original cause (logged via console.error) and re-throws a generic message, so the real failure — heic-to dynamic import error, libheif decode failure, unsupported HEIC variant, or out-of-memory on large files — is only visible in the browser console. The function is invoked transitively through processFileForUpload whenever isHEICFile returns true.

Source

Thrown at client/src/utils/heicConverter.ts:76

      quality,
    });

    // Report conversion completion
    onProgress?.(0.8);

    // Create a new File object with the converted blob
    const convertedFile = new File([convertedBlob], file.name.replace(/\.(heic|heif)$/i, '.jpg'), {
      type: 'image/jpeg',
      lastModified: file.lastModified,
    });

    // Report file creation completion
    onProgress?.(1.0);

    return convertedFile;
  } catch (error) {
    console.error('Error converting HEIC to JPEG:', error);
    throw new Error('Failed to convert HEIC image to JPEG');
  }
};

/**
 * Process a file, converting it from HEIC to JPEG if necessary
 * @param file - The file to process
 * @param quality - JPEG quality for conversion (0-1), default is 0.9
 * @param onProgress - Optional callback to track conversion progress
 * @returns Promise<File> - The processed file (converted if it was HEIC, original otherwise)
 */
export const processFileForUpload = async (
  file: File,
  quality: number = 0.9,
  onProgress?: (progress: number) => void,
): Promise<File> => {
  const isHEIC = await isHEICFile(file);

  if (isHEIC) {

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Open the browser console — the line logged just above this throw ('Error converting HEIC to JPEG:') carries the underlying cause; fix that first.
  2. If the dynamic import is failing, verify 'heic-to' is in client/package.json and that your bundler emits the lazy chunk on the same origin.
  3. If decode fails on a specific file, reject it client-side after isHEICFile and surface a user-facing message instead of retrying.
  4. For very large images, downscale or cap file size before calling convertHEICToJPEG to avoid OOM.
  5. Wrap the caller of processFileForUpload in try/catch and fall back to uploading the original file or showing an inline error.

Example fix

// before
try {
  await convertHEICToJPEG(file);
} catch (e) {
  // opaque error
}

// after — let the original cause through for diagnosis
} catch (error) {
  console.error('Error converting HEIC to JPEG:', error);
  throw new Error(`Failed to convert HEIC image to JPEG: ${error instanceof Error ? error.message : 'unknown'}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { isHEICFile } from '~/utils/heicConverter';

async function safeProcess(file: File) {
  if (await isHEICFile(file)) {
    // best-effort; conversion may still fail inside
    if (file.size > 25 * 1024 * 1024) {
      throw new Error('HEIC file too large to convert client-side');
    }
  }
  return file;
}

Type guard

const isFileLike = (v: unknown): v is File =>
  v != null && typeof v === 'object' && 'name' in v && 'size' in v && 'type' in v;

Try / catch

try {
  const processed = await processFileForUpload(file);
  await upload(processed);
} catch (error) {
  if (error instanceof Error && error.message.includes('Failed to convert HEIC')) {
    showUserError('Could not convert this HEIC image. Try a JPEG or PNG.');
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Uploading a file whose MIME type or extension matches image/heic|heif AND any of: (a) the 'heic-to' dynamic import fails (network/CSP/bundler misconfig), (b) heicTo() rejects on a corrupt or non-conformant HEIC bitstream, (c) the browser runs out of memory decoding a very large image, or (d) WebAssembly support is disabled where libheif needs it.

Common situations: iOS users uploading photos in default HEIC format; older browsers or Safari versions with partial HEIC support; a bundler that cannot code-split the heic-to chunk; CSP rules blocking the dynamic import or the wasm blob; files renamed to .heic that are not actually HEIC.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/fdf86ebeb044286f. Report an issue: GitHub.