I'm using Angular, and I have my server.js that, when uploading an image, Sharp creates a thumbnail. The main issue is that if later I want to delete the main image, it won't let me because something is using it. File not accessible: C:\Users\...\uploads\Fan-Art\test-1738586514023.jpg Error: EPERM: operation not permitted, unlink 'C:\Users\...\furwork\uploads\Fan-Art\test-1738586514023.jpg' Even if I try to delete the image manually, it tells me that something is using it and prevents to delete it. But if I stop the server.js I can delete it without any problem. I tried not to create a thumbnail, and I could delete the image accordingly without any problem, deleting it from the website and manually. This is my endpoint on the server.js app.post('/upload-submission', upload.any(), async (req, res) => { const folderPath = req.body.folderPath; const targetDir = path.join(__dirname, folderPath); console.log('Resolved path:', targetDir); if (!fs.existsSync(targetDir)) { console.log(`Path ${targetDir} does not exist.`); return res.status(400).json({ error: `Path ${targetDir} does not exist.` }); } try { let mainFile = null; let additionalImages = []; // Process uploaded files for (const file of req.files) { const fileExt = path.extname(file.originalname); let fileName; if (file.fieldname === 'image') { // Handle main image fileName = `${req.body.fileId}${fileExt}`; mainFile = { path: path.join(folderPath, fileName) }; } else if (file.fieldname.startsWith('image-')) { // Handle additional images fileName = `${req.body.fileId}-${file.fieldname}${fileExt}`; additionalImages.push({ path: path.join(folderPath, fileName) }); } else { continue; } // Move file to target directory const uploadedFilePath = path.join(targetDir, fileName); await fs.promises.rename(file.path, uploadedFilePath); } if (!mainFile) { return res.status(400).json({ error: 'Main image is required.' }); } // Generate the thumbnail and ensure it finishes before proceeding const thumbnailName = `thumb-${path.basename(mainFile.path)}`; const thumbnailPath = path.join(targetDir, thumbnailName); try { // This ensures the Sharp process finishes before continuing await sharp(path.join(targetDir, path.basename(mainFile.path))) .resize(150, 150) .toFile(thumbnailPath); console.log("Thumbnail created successfully."); } catch (err) { console.error('Error creating thumbnail:', err); throw new Error('Error creating thumbnail'); } // Add metadata const metadata = { path: mainFile.path, thumbnail: path.join(folderPath, thumbnailName), title: req.body.title, description: req.body.description, rating: req.body.rating, keywords: JSON.parse(req.body.keywords), id: req.body.fileId, price: req.body.price, additionalImages: additionalImages // Store array of additional images }; const jsonFilePath = path.join(targetDir, 'images.json'); let images = []; try { const data = await fs.promises.readFile(jsonFilePath, 'utf8'); images = JSON.parse(data); } catch (readErr) { if (readErr.code !== 'ENOENT') { console.log('Error parsing images.json'); return res.status(500).json({ error: 'Error parsing images.json' }); } } images.unshift(metadata); await fs.promises.writeFile(jsonFilePath, JSON.stringify(images, null, 2)); // Add a small delay to ensure the file handle is released setTimeout(() => { res.status(200).json({ message: 'Images uploaded successfully', metadata }); }, 1000); // Delay of 1000ms to allow file handle to be released } catch (err) { console.error('An error occurred:', err); res.status(500).json({ error: 'An error occurred during the upload process.' }); } }); Versions using: "express": "^4.21.1", "axios": "^1.7.8", "sharp": "^0.33.5", "multer": "^1.4.5-lts.1", "@angular/core": "^18.2.0", Hope you can help me with this! Continue reading...