Node.js sporadically failing to write file with: Error: ENOENT, open 'filename'

javascript, node.js

Solution

It's possible you're running into the fact that files in Node aren't written with `O_SYNC` when written asynchronously. Which means that you might be trying to access the file before the kernel has flushed it to disk. There's a little more reading here (under the header `fs.writeFile()`): http://www.daveeddy.com/2013/03/26/synchronous-file-io-in-nodejs/

EDIT: Here is an example to forcefully demonstrate the problem:

var fs = require('fs');
var fname = '/tmp/fs.' + process.pid + '.tmp';
var buf = new Buffer(1024);
buf.fill('a');

fs.writeFile(fname, buf, function(err) {
  console.log(err);
});

try {
  fs.readFileSync(fname);
} catch(e) {
  console.log(e.stack);
}

process.on('exit', function() {
  try { fs.unlinkSync(fname); } catch(e) {}
});

// Output:
// Error: ENOENT, no such file or directory '/tmp/fs.31281.tmp'

Problem

I am working on a node.js application that accesses the file system. In my testing, I have noticed something very strange that google has not been able to answer for me. My code works fine 95% of the time, however, on occasion, I get this error: "Error: ENOENT, open 'test.Q3rax'" where test.Q3rax is a randomly generate filename. That file should be writeable, and if I run my code again, with the filename hardcoded in, it works just fine. Here is the code where it is failing: ``` npJSON.prototype._writeFile = function(newData) { if (!this.loaded) throw "ERROR: npJSON._writeFile() was called before any data was loaded."; var stringToWrite = JSON.stringify(newData); fs.writeFile(this.fileName,stringToWrite, function(err) { if (err) throw err; }); }; ``` Edit: For clarification, this is how I am generating the random filenames: ``` var filename = 'test.' + getRandomText(5,6); function getRandomText(numberOfCharactersLow, numberOfCharactersHigh) { var numbChar = getRandomInt(numberOfCharactersLow, numberOfCharactersHigh); var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; var returnText = ''; for (var i = 0; i < numbChar; i++) { returnText += possible.charAt(getRandomInt(0, 62)); } return returnText; } function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } ```

Original source

Related problems