danny-avila/LibreChat · error · Error

Invalid base64 string

Error message

Invalid base64 string

What it means

Thrown by base64ToBuffer after stripping the optional `data:<type>;base64,` prefix if the remaining string is empty. This catches inputs that were only the prefix (`data:image/png;base64,` with no payload) or an empty string after stripping. The function returns buffer+type, so an empty payload has nothing to decode.

Source

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

    logger.debug(`[retrieveAndProcessFile] Non-image file type detected: ${basename}`);
    return await processOpenAIFile({ ...processArgs, saveFile: true });
  }
}

/**
 * Converts a base64 string to a buffer.
 * @param {string} base64String
 * @returns {Buffer<ArrayBufferLike>}
 */
function base64ToBuffer(base64String) {
  try {
    const typeMatch = base64String.match(/^data:([A-Za-z-+/]+);base64,/);
    const type = typeMatch ? typeMatch[1] : '';

    const base64Data = base64String.replace(/^data:([A-Za-z-+/]+);base64,/, '');

    if (!base64Data) {
      throw new Error('Invalid base64 string');
    }

    return {
      buffer: Buffer.from(base64Data, 'base64'),
      type,
    };
  } catch (error) {
    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();

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Ensure the full base64 payload is included after the `data:<type>;base64,` prefix.
  2. Validate on the client that the data URL body is non-empty before submit.
  3. If the input is a plain (non-data-URL) base64 string, note the regex only strips the optional prefix — a plain empty string still trips this.
  4. Check the producer of the data URL (e.g., FileReader.readAsDataURL) completes before the value is sent.

Example fix

// before
await saveBase64Image('data:image/png;base64,', ctx);

// after: ensure the body is captured
const dataUrl = await fileToDataUrl(file); // resolves full data URL
if (!dataUrl.split(',')[1]) throw new Error('Empty image payload');
await saveBase64Image(dataUrl, ctx);
Defensive patterns

Strategy: validation

Validate before calling

function assertBase64Body(dataUrl) {
  const body = typeof dataUrl === 'string'
    ? dataUrl.replace(/^data:[^;]+;base64,/, '')
    : '';
  if (!body) throw new Error('Empty base64 payload');
  return body;
}

Try / catch

try { base64ToBuffer(s); }
catch (e) {
  if (/Invalid base64 string/.test(e.message)) return res.status(400).json({ error: 'Image payload is empty' });
  throw e;
}

Prevention

When it happens

Trigger: A data-URL with an empty base64 body; a string that is just the MIME prefix; calling base64ToBuffer('') or base64ToBuffer('data:image/png;base64,') — anything where the regex strips the content down to nothing.

Common situations: Frontend paste handler that captured the data URL header but not the body due to truncation; a copy/paste that dropped the payload; a generated data URL from a failed canvas.toDataURL (rare); upstream serialization that split the string.

Related errors


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