danny-avila/LibreChat · error · Error

Could not determine file extension from MIME type: ${type}

Error message

Could not determine file extension from MIME type: ${type}

What it means

Thrown by saveBase64Image when the parsed MIME `type` from the data URL prefix yields no extension via `mime.getExtension(type)` AND the supplied `_filename` has no extension already. The function needs a file extension to build a storage filename; without one (and no resolvable MIME extension), it refuses rather than store an extension-less file.

Source

Thrown at api/server/services/Files/process.js:1269

    throw new Error(`Failed to convert base64 to buffer: ${error.message}`);
  }
}

async function saveBase64Image(
  url,
  { req, file_id: _file_id, filename: _filename, endpoint, context, resolution },
) {
  const appConfig = req.config;
  const effectiveResolution = resolution ?? appConfig.fileConfig?.imageGeneration ?? 'high';
  const file_id = _file_id ?? v4();
  let filename = `${file_id}-${_filename}`;
  const { buffer: inputBuffer, type } = base64ToBuffer(url);
  if (!path.extname(_filename)) {
    const extension = mime.getExtension(type);
    if (extension) {
      filename += `.${extension}`;
    } else {
      throw new Error(`Could not determine file extension from MIME type: ${type}`);
    }
  }

  const image = await resizeImageBuffer(inputBuffer, effectiveResolution, endpoint);
  const source = getFileStrategy(appConfig, { isImage: true });
  const { saveBuffer } = getStrategyFunctions(source);
  const filepath = await saveBuffer({
    userId: req.user.id,
    fileName: filename,
    buffer: image.buffer,
    tenantId: req.user.tenantId,
  });
  const storageMetadata = getStorageMetadata({ filepath, source });
  return await db.createFile(
    {
      type,
      source,
      context,

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Use the canonical MIME spelling: `image/jpeg` (not `image/jpg`), `image/png`, `image/webp`, `image/gif`.
  2. Pass a filename that already has the correct extension, so the MIME-extension lookup is skipped.
  3. Sanitize the MIME segment before calling: ensure it matches `^[a-z]+/[a-z0-9.+-]+$`.
  4. If you genuinely need a custom type, add an extension on `_filename` to bypass the lookup.

Example fix

// before
saveBase64Image('data:image/jpg;base64,...', { req, filename: 'avatar' });

// after
saveBase64Image('data:image/jpeg;base64,...', { req, filename: 'avatar.jpg' });
Defensive patterns

Strategy: validation

Validate before calling

const MIME_EXT = { 'image/jpeg': 'jpg', 'image/png': 'png', 'image/webp': 'webp', 'image/gif': 'gif' };
function ensureFilenameExt(filename, mime) {
  if (path.extname(filename)) return filename;
  const ext = MIME_EXT[mime] || mime.getExtension(mime);
  if (!ext) throw new Error(`Unknown MIME type: ${mime}`);
  return `${filename}.${ext}`;
}

Try / catch

try { await saveBase64Image(url, ctx); }
catch (e) {
  if (/Could not determine file extension/.test(e.message)) return res.status(400).json({ error: 'Unrecognized image MIME type' });
  throw e;
}

Prevention

When it happens

Trigger: Caller passes a `data:` URL whose MIME segment is unregistered or malformed (e.g., `data:image-jpg;base64,` — note the dash instead of slash — or `data:foo/bar;base64,`) AND omits an extension on `_filename`. mime.getExtension returns undefined for unknown MIME strings, triggering the throw.

Common situations: Producer emits a typo'd MIME like `image/jpg` (mime expects `image/jpeg`), `image/png-`, or a private/custom MIME; client sends `filename: 'avatar'` (no extension) alongside such a MIME; hand-crafted data URLs with incorrect Content-Type segments.

Related errors


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