ENOENT: no such file or directory .?
Asked Answered
E

29

42

This is error which am getting while post data and file. I have followed 'academind' tutorial for building Restful API services, also i have been searching answer for this type of errors but nothing works for me.

Am using "multer" to upload file

The folder 'uploads' available in the folder but it shows

ENOENT: no such file or directory, open 'D:\project\uploads\2018-01-24T07:41:21.832Zcheck.jpg'"

app.js

const express = require("express");
const app = express();
const morgan = require("morgan");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");

const productRoutes = require("./api/routes/products");

mongoose.connect('',
(err)=>{
    if(err){console.log(err)}
    else{console.log('DB Connected')}
})
mongoose.Promise = global.Promise;

app.use(morgan("dev"));
app.use('/uploads', express.static('uploads'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept, Authorization"
  );
  if (req.method === "OPTIONS") {
    res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET");
    return res.status(200).json({});
  }
  next();
});

// Routes which should handle requests
app.use("/products", productRoutes);

app.use((req, res, next) => {
  const error = new Error("Not found");
  error.status = 404;
  next(error);
});

app.use((error, req, res, next) => {
  res.status(error.status || 500);
  res.json({
    error: {
      message: error.message
    }
  });
});

module.exports = app;

product.js

const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const multer = require('multer');

const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }
});

const fileFilter = (req, file, cb) => {
  // reject a file
  if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
    cb(null, true);
  } else {
    cb(null, false);
  }
};

const upload = multer({
  storage: storage,
  limits: {
    fileSize: 1024 * 1024 * 5
  },
  fileFilter: fileFilter
});

router.post("/", checkAuth, upload.single('productImage'), (req, res, next) => {
  const product = new Product({
    _id: new mongoose.Types.ObjectId(),
    name: req.body.name,
    price: req.body.price,
    productImage: req.file.path 
  });
  product
    .save()
    .then(result => {
      console.log(result);
      res.status(201).json({
        message: "Created product successfully",
        createdProduct: {
            name: result.name,
            price: result.price,
            _id: result._id,
            request: {
                type: 'GET',
                url: "http://localhost:3000/products/" + result._id
            }
        }
      });
    })
    .catch(err => {
      console.log(err);
      res.status(500).json({
        error: err
      });
    });
});

module.exports = router;
Earphone answered 24/1, 2018 at 9:14 Comment(1)
According to this page, colons (:) are not allowed in filenames. Try removing it (line 11 in product.js).Artel
D
98

in product.js:

After new Date().toISOString() add replace() to change ":" to an accepted character.

Windows OS doesn't accept files with a ":"

The person on Youtube is using MAC OS

E.g

new Date().toISOString().replace(/:/g, '-')

Dibromide answered 7/2, 2018 at 0:3 Comment(2)
Thank you for this. Had the same issue and this solved it for meSkill
This answer deserves more upvotes.Iridescence
I
25

Try the following:

  1. Require this as a constant (const path = require('path');)
  2. Change this line

    cb(null, './uploads/');

With this:

cb(null, path.join(__dirname, '/uploads/'));

As I can see, you are trying to get a path that is not on served on the server, but rather a path that is on the server machine.

UPDATE

Try also changing this

app.use('/uploads', express.static('uploads'));

To this:

app.use(express.static(__dirname));

In order to expose the __dirname for static files.

Inscrutable answered 24/1, 2018 at 9:31 Comment(5)
i have added 'cb(null, 'D:/project/uploads');' but still sameEarphone
Do not use 'D:/project/uploads', use the __dirname global objects. nodejs.org/docs/latest/api/modules.html#modules_dirnameInscrutable
same error, console.log(__dirname) results D:\projectEarphone
The error must be somewhere with the express.static not able to host your folder for static filesInscrutable
Thank you so so much. saved me many hours of stress. adding next(null, path.join(__dirname, '.././public/uploads/images/')); workedGadoid
D
7

This what worked for me. I changed './uploads/' into '__dirname' so that it can find the correct directory/filename anywhere on your computer.

const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, __dirname);
  },
  filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }
});

Because when you set a specific folder name/directory you limit your image directory to be only or should be in that folder.

Dichromatic answered 3/2, 2020 at 6:56 Comment(2)
Thank you. It's Working.Szombathely
Thank you.This worked for me, but I have no idea why I was getting such errors in the first place.Mcguinness
E
7

So the answer is in the tutorials comments section on youtube. Instead of:

cb(null, new Date().toISOString() + file.originalname);

do:

cb(null, Date.now() + file.originalname);

Simple as.

Elysium answered 19/2, 2020 at 16:29 Comment(0)
S
4

I am doing the same course and I too had the same problem (i also use windows machine). The following worked for me:

const hash = require('random-hash'); // you have to install this package:

const fileStorage = multer.diskStorage({
    destination: (req, file, callback) => { //this is storing the file in the images folder
        callback(null, path.join(__dirname, '/Images'));
    },

    filename: (req, file, callback) => { //this is just setting a unique filename
        let temp = file.originalname.split('.');
        const filename = temp[0] + '-' + hash.generateHash({length: 5}) + '.' + temp[1]
        callback(null, filename);
    }
});

This creates a unique hash for the filenames as well

Selfexcited answered 20/11, 2020 at 11:36 Comment(1)
You can also use node's built in crypto lib to generate the hash. So, you won't have to add another dependency. crypto.randomBytes(16).toString("hex") -> this bit will generate the hashLucialucian
B
3

I found this in the comments section, here: https://www.youtube.com/watch?v=srPXMt1Q0nY&list=PL55RiY5tL51q4D-B63KBnygU6opNPFk_q&index=10

OK guys, in case someone has an issue with this in the file creation stage, that probably means you're working on Windows. Now, you don't need to feel discouraged and throw your computer to the trash (I actually like always having to find workarounds for my Windows :).

There's at least a solution, and this is the one I found. My problem is the file does not get created because Windows does not accept filenames with colon (':') on it. My solution is rather simple. After I get the current date, I use replace() and a regexp to change that into a dash. Viola. It works!

Just in case, this is one way to do it: filename: function(req, file, cb){ const now = new Date().toISOString(); const date = now.replace(/:/g, '-'); cb(null, date + file.originalname); }

Hope it helps someone who´s working in windows.

Baptistry answered 5/2, 2018 at 23:38 Comment(0)
H
2

I came across the same error while saving the file. The path I provided in callback didn't exist already that's why I got that error

const fs = require('fs');
const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    fs.mkdir('./uploads/',(err)=>{
       cb(null, './uploads/');
    });
  },
  filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }
});

With filesystem I created the same folder, In case of folder exists the err gets value but here nothing to worry about as we have that folder. This worked for me. hope this would help

Humdinger answered 8/8, 2020 at 11:13 Comment(1)
Yeah... it took me an hour to figure out that folder should be already there only then it saves the file.Hypnosis
P
2

I had a similar error and this is how I resolved it. After using the replace method, I changed './uploads/images/' to 'uploads/images'. In this case, multer created the folder automatically. So you have something like this

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
    cb(null, 'uploads/');
    },
    filename: function(req, file, cb) {
     cb(null, new Date().toISOString().replace(/:/g, '-')+ file.originalname);
      }
  });

For Windows users.

Pericarditis answered 24/10, 2020 at 6:42 Comment(0)
N
2

This error occurs because ./uploads/ does not exist.

FYI : If you use multer like below

const upload = multer({ dest: 'uploads' })

This creates uploads directories at server starting.

but if we use destination object then it does not create directory.

Proof/ref: https://www.npmjs.com/package/multer#diskstorage https://www.npmjs.com/package/multer#diskstorage

Solution

const fs = require('fs'); // Added to create directories
const multer = require('multer');

const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    // :::::::::::::::Create diretories:::::::::::::::::::
    fs.mkdir('./uploads/',(err)=>{
       cb(null, './uploads/');
    });
  },
  filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }
});

const fileFilter = (req, file, cb) => {
  // reject a file
  if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
    cb(null, true);
  } else {
    cb(null, false);
  }
};

const upload = multer({
  storage: storage,
  limits: {
    fileSize: 1024 * 1024 * 5
  },
  fileFilter: fileFilter
});
Nought answered 24/5, 2022 at 15:36 Comment(0)
L
2

What worked for me:(Windows OS)

const path = require("path");
const multer = require("multer");

const fileStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, path.join(__dirname, "Images")); 
//Images is folder which will hold uploaded images
  },
  filename: (req, file, cb) => {
    cb(null, new Date().toISOString().replace(/:/g, "-") + file.originalname);
  },
});

app.use(multer({ storage: fileStorage }).single("image")); //Middleware
Levelheaded answered 13/2, 2023 at 18:14 Comment(0)
C
1

every thing is fine. problem is on this line cb(null, new Date().toISOString() + file.originalname); simply write cb(null,file.originalname); it will work. try to use in different way to add the date string with file name.

Compatriot answered 2/6, 2019 at 14:44 Comment(0)
S
1

You don't have permission to access /uploads/ on this server.

Try the following:

sudo chmod -R 777 /uploads
Sower answered 14/11, 2019 at 8:0 Comment(0)
E
1

You should change the file name. Because ':' is not allowed in Windows.

Eg:

const storage = multer.diskStorage({
    destination: function(req, file, cb){
        cb(null,'./uploads/');
    },
    filename: function(req,file,cb){
        cb(null, new Date().toISOString().replace(/:/g, '-') +'-'+ file.originalname);
    }
});
Elman answered 26/4, 2020 at 4:43 Comment(0)
I
1

I think if you work with Windows OS, you should use another methods of Date().i write code like this:

filename:(req,file,cb)=>{ cb(null,new Date().toDateString()+file.originalname) }
Iwo answered 30/8, 2020 at 8:5 Comment(0)
N
1

create folder uploads near app.js file

for this line

app.use('/uploads', express.static('uploads'));
Nernst answered 29/10, 2020 at 21:11 Comment(0)
A
1

use this = > cb(null, Date.now() + file.originalname); instead of cb(null, new Date().toISOString() + file.originalname); to prevent "error": "ENOENT: no such file or directory

Alsacelorraine answered 10/12, 2020 at 5:35 Comment(0)
O
1

if this can't find a folder then you can create one

destination: function(req, file, cb) {
    fs.mkdir('./uploads/',(err)=>{
       cb(null, './uploads/');
    });
  },
Oligocene answered 6/4, 2021 at 3:32 Comment(0)
C
1

Going out on a limb here, many other people are very close and I'm sure that some of the answers work for some people, but nothing short of this answer I found here has worked for me (struggled with this for 2 weeks now).

    const storage = multer.diskStorage({

  destination: function (req, file, cb) {
    cb(null, path.resolve(__dirname, './test'))
  },

  filename: function (req, file, cb) {
    cb(null, file.originalname)
  }
})
Crew answered 13/8, 2021 at 8:44 Comment(1)
Worked for me! Important answer if all the others aren't working for youTrustless
F
0

Note: In order to remove all special character, we can use replace function as

const cleanVariable = mixSpecialCharters.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');
Femininity answered 28/11, 2020 at 6:52 Comment(0)
C
0
const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    -cb(null, './uploads/');
    +cb(null, 'upload/');
  },
  filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }
});
Clausius answered 9/2, 2021 at 2:17 Comment(1)
add more detailsIndifferentism
H
0

in product.js just replace cb(null, new Date().toISOString()+ file.originalname) with cb(null, Date.now() + "-" + file.originalname);

Hay answered 13/8, 2021 at 0:32 Comment(0)
F
0

just change

cb(null, new Date().toISOString() + file.originalname);

with

cb(null, Date.now() + file.originalname);
Finkelstein answered 17/8, 2021 at 22:23 Comment(0)
R
0

Here is how you can avoid any directory issues

const path = require("path");
const multer = require("multer");

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path.join(__dirname, "../uploads"));
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
    cb(null, file.fieldname + "-" + uniqueSuffix + file.originalname);
  },
});
Runty answered 27/4, 2022 at 15:27 Comment(0)
R
0

const storage = multer.diskStorage({
    destination: function(req,file,cb){
        //if that dir is not created then this will create that dir first
        fs.mkdir('./uploads/',(err)=>{
            cb(null,'./uploads/');
        })
    },
    filename: function(req,file,cb)
    {
        cb(null,new Date().toISOString().replace(/:/g, '-') +'-'+file.originalname);
    }
})

this happens in windows and in mac due to ':' so just replace it

Ruysdael answered 31/5, 2022 at 15:54 Comment(0)
W
0

As others suggest it is indeed an issue with how the OS is handeling parts of the date string, namely the ':'. The purpose of this new Date().toISOString() is generating some randmoness, which can also be achieved with another 3rd party package like UUID for example:

filename: (req, file, cb) => cb(null, `${uuidv4()}-${file.originalname}`)

of course to use this library you have to install it and then refer it:

const { v4: uuidv4 } = require("uuid")
Wayside answered 6/7, 2022 at 8:46 Comment(0)
D
0

`const path = require("path");

const multer = require("multer");

const dir = __dirname;

const fileStorage = multer.diskStorage({

destination: function (req, file, cb) {

cb(null, path.extname(dir + "/public/my-uploads"));

},

filename: function (req, file, cb) { cb(null, Date.now() + "-" + file.originalname);

},

});

module.exports = { fileStorage }; ` This Worked for me.

Dig answered 6/9, 2022 at 1:45 Comment(0)
P
0

try

const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, path.join(__dirname,'../uploads/');
  },
  filename: function(req, file, cb) {
    cb(null, Date.now() + file.originalname);
  }
});

also for filename change new Date() into Date.now()

Paragon answered 1/10, 2022 at 20:15 Comment(0)
R
0

Try to change the dist folder from ./uploads/ to uploads/

in this function

const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }
});
Rancher answered 9/11, 2022 at 16:17 Comment(0)
M
0

In order to make it work, change this:

filename: function(req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname);
  }

to

  filename:(req,file,cb)=>{
        const name = Date.now()+file.originalname;
        cb(null, name);
    }
Mcniel answered 18/10, 2023 at 10:49 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.