gitroomhq/postiz-app · error · BadRequestException

Invalid file upload.

Error message

Invalid file upload.

What it means

The custom upload validation pipe throws 'Invalid file upload.' when the value looks like a file object (has buffer/mimetype/fieldname keys) but value.buffer is missing or not a Node Buffer. It runs as a NestJS transform pipe on any file-typed parameter, so it fires before MIME or size checks.

Source

Thrown at libraries/nestjs-libraries/src/upload/custom.upload.validation.ts:33

  'image/bmp',
  'image/tiff',
  'video/mp4',
]);

@Injectable()
export class CustomFileValidationPipe implements PipeTransform {
  async transform(value: any) {
    if (!value || typeof value !== 'object') {
      return value;
    }

    // Skip non-file parameters (org, body, query, etc.)
    if (!('buffer' in value) && !('mimetype' in value) && !('fieldname' in value)) {
      return value;
    }

    if (!value.buffer || !Buffer.isBuffer(value.buffer)) {
      throw new BadRequestException('Invalid file upload.');
    }

    const detected = await fileTypeFromBuffer(value.buffer);
    if (!detected || !ALLOWED_MIME_TYPES.has(detected.mime)) {
      throw new BadRequestException('Unsupported file type.');
    }

    const maxSize = getMaxSize(detected.mime);
    if (value.size > maxSize) {
      throw new BadRequestException(
        `File size exceeds the maximum allowed size of ${maxSize} bytes.`
      );
    }

    value.mimetype = detected.mime;
    const safeBase = (value.originalname || 'upload')
      .replace(/\.[^./\\]*$/, '')
      .replace(/[\\/]/g, '_')

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Ensure the client actually attaches a file in the multipart part and it is non-empty
  2. Confirm Multer is configured with memory storage and no other middleware reads the stream first
  3. Log value.buffer and Object.keys(value) at the pipe to see what shape arrives
  4. Return a 400 to the client with a clear message that the file part is missing/corrupt

Example fix

// client: ensure a real file is attached
const form = new FormData();
form.append('file', fileInput.files[0]); // not undefined/empty

// server-side guard before calling the API
if (!file || file.size === 0) throw new Error('Attach a non-empty file');
Defensive patterns

Strategy: validation

Validate before calling

function isMulterFile(v: unknown): v is Express.Multer.File {
  return !!v && typeof v === 'object' && 'buffer' in v && 'mimetype' in v && 'fieldname' in v;
}
// only call the endpoint when isMulterFile(req.file) && req.file.buffer.length > 0

Type guard

function isMulterFile(v: unknown): v is Express.Multer.File {
  return !!v && typeof v === 'object' && 'buffer' in v && 'mimetype' in v && 'fieldname' in v && Buffer.isBuffer((v as any).buffer); 
}

Try / catch

try { await controller.upload(dto); } catch (e) { if (e instanceof BadRequestException && e.message === 'Invalid file upload.') showFormError('File missing or unreadable — re-attach it.'); else throw e; }

Prevention

When it happens

Trigger: A multipart request where the file part arrives without a readable buffer (empty file part, stream consumed elsewhere, middleware order issue), or a crafted payload that partially resembles a Multer file object. Non-file values are skipped, so this only fires for file-shaped inputs.

Common situations: Sending multipart/form-data with an empty file input; a middleware or an earlier pipe consuming the stream; using a custom parser instead of Multer memory storage; proxy (nginx/CDN) stripping the file body.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/1014f3623be0720c. Report an issue: GitHub.