{"record":{"id":"1014f3623be0720c","repo":"gitroomhq/postiz-app","slug":"invalid-file-upload","errorCode":null,"errorMessage":"Invalid file upload.","messagePattern":"Invalid file upload\\.","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"libraries/nestjs-libraries/src/upload/custom.upload.validation.ts","lineNumber":33,"sourceCode":"  'image/bmp',\n  'image/tiff',\n  'video/mp4',\n]);\n\n@Injectable()\nexport class CustomFileValidationPipe implements PipeTransform {\n  async transform(value: any) {\n    if (!value || typeof value !== 'object') {\n      return value;\n    }\n\n    // Skip non-file parameters (org, body, query, etc.)\n    if (!('buffer' in value) && !('mimetype' in value) && !('fieldname' in value)) {\n      return value;\n    }\n\n    if (!value.buffer || !Buffer.isBuffer(value.buffer)) {\n      throw new BadRequestException('Invalid file upload.');\n    }\n\n    const detected = await fileTypeFromBuffer(value.buffer);\n    if (!detected || !ALLOWED_MIME_TYPES.has(detected.mime)) {\n      throw new BadRequestException('Unsupported file type.');\n    }\n\n    const maxSize = getMaxSize(detected.mime);\n    if (value.size > maxSize) {\n      throw new BadRequestException(\n        `File size exceeds the maximum allowed size of ${maxSize} bytes.`\n      );\n    }\n\n    value.mimetype = detected.mime;\n    const safeBase = (value.originalname || 'upload')\n      .replace(/\\.[^./\\\\]*$/, '')\n      .replace(/[\\\\/]/g, '_')","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/upload/custom.upload.validation.ts#L15-L51","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the client actually attaches a file in the multipart part and it is non-empty","Confirm Multer is configured with memory storage and no other middleware reads the stream first","Log value.buffer and Object.keys(value) at the pipe to see what shape arrives","Return a 400 to the client with a clear message that the file part is missing/corrupt"],"exampleFix":"// client: ensure a real file is attached\nconst form = new FormData();\nform.append('file', fileInput.files[0]); // not undefined/empty\n\n// server-side guard before calling the API\nif (!file || file.size === 0) throw new Error('Attach a non-empty file');","handlingStrategy":"validation","validationCode":"function isMulterFile(v: unknown): v is Express.Multer.File {\n  return !!v && typeof v === 'object' && 'buffer' in v && 'mimetype' in v && 'fieldname' in v;\n}\n// only call the endpoint when isMulterFile(req.file) && req.file.buffer.length > 0","typeGuard":"function isMulterFile(v: unknown): v is Express.Multer.File {\n  return !!v && typeof v === 'object' && 'buffer' in v && 'mimetype' in v && 'fieldname' in v && Buffer.isBuffer((v as any).buffer); \n}","tryCatchPattern":"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; }","preventionTips":["Always attach a non-empty file part in multipart requests","Use Multer memory storage consistently","Never consume the upload stream in earlier middleware"],"tags":["nestjs","upload","validation","multer"],"backgroundTag":"multipart-upload-invalid","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}