danny-avila/LibreChat · error
Invalid input type. Expected URL, Buffer, or File.
Error message
Invalid input type. Expected URL, Buffer, or File.
What it means
Thrown by the input-type dispatch in the avatar uploader when `input` is none of: string (treated as URL), Buffer (raw bytes), or a File object (with a `.path`). This is the fallback else-branch after all three supported input shapes are checked. It prevents passing arbitrary objects (e.g., a plain object, a number, a ReadStream) into sharp(), which would produce a confusing downstream error.
Source
Thrown at api/server/services/Files/images/avatar.js:107
* @throws {Error} Throws an error if the user ID is undefined, the input type is invalid, the image fetching fails,
* or any other error occurs during the processing.
*/
async function resizeAvatar({ userId, input, desiredFormat = EImageOutputType.PNG, fetchOptions }) {
try {
if (userId === undefined) {
throw new Error('User ID is undefined');
}
let imageBuffer;
if (typeof input === 'string') {
imageBuffer = await fetchAvatarBuffer(input, fetchOptions);
} else if (input instanceof Buffer) {
imageBuffer = input;
} else if (typeof input === 'object' && input instanceof File) {
const fileContent = await fs.readFile(input.path);
imageBuffer = Buffer.from(fileContent);
} else {
throw new Error('Invalid input type. Expected URL, Buffer, or File.');
}
const metadata = await sharp(imageBuffer).metadata();
const { width, height } = metadata;
const minSize = Math.min(width, height);
if (metadata.format === 'gif') {
const resizedBuffer = await sharp(imageBuffer, { animated: true })
.extract({
left: Math.floor((width - minSize) / 2),
top: Math.floor((height - minSize) / 2),
width: minSize,
height: minSize,
})
.resize(250, 250)
.gif()
.toBuffer();
View on GitHub (pinned to 5ff282f900)
Solutions
- Ensure `input` is one of: a URL string, a Node Buffer, or an Express/Multer File object.
- Convert browser `Uint8Array`/`ArrayBuffer` via `Buffer.from(uint8)` before calling.
- For form uploads, route through the request's `req.file` (Multer) so a File object is passed.
- Add a TypeScript discriminated union on the input parameter to catch mismatches at compile time.
Example fix
// before
await uploadAvatar({ userId, input: { data: bytes } });
// after
await uploadAvatar({ userId, input: Buffer.from(bytes) }); Defensive patterns
Strategy: type-guard
Type guard
/** @param {unknown} i */
function isValidAvatarInput(i) {
if (typeof i === 'string') return true;
if (Buffer.isBuffer(i)) return true;
return typeof i === 'object' && i !== null && 'path' in i && typeof i.path === 'string';
} Try / catch
try { await uploadAvatar({ userId, input }); }
catch (e) {
if (/Invalid input type/.test(e.message)) return res.status(400).json({ error: 'Avatar must be a URL, Buffer, or File.' });
throw e;
} Prevention
- Type the uploadAvatar `input` parameter as a discriminated union so TS catches misuse at compile time.
- Convert browser ArrayBuffer/Uint8Array via Buffer.from before sending.
- For multipart uploads, pass the Multer File (req.file) directly.
When it happens
Trigger: Calling uploadAvatar with `input` that is a plain object, number, boolean, ReadStream, ArrayBuffer, Uint8Array (not a Buffer), or a front-end FormData value that wasn't materialized into a File. Also passing `null` or `undefined` after a preceding check expects a different shape.
Common situations: Frontend sending a JSON-serialized blob instead of multipart FormData; an integration passing a `Uint8Array` from a browser API instead of converting to Buffer; misrouted call where the caller assumed uploadAvatar accepts a ReadStream.
Related errors
- Invalid avatar URL
- Missing required field: prompt
- Missing required field: prompt
- Missing required field: finetune_id for finetuned generation
- Invalid endpoint for finetuned generation. Must be one of: $
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/045575f369824c41.
Report an issue: GitHub.