Skip to content

fs: use w flag for writeFileSync with utf8 encoding when flag not specified

PR https://github.com/nodejs/node/pull/49884 seems to have accidentally changed the behavior for fs.writeFileSync with utf-8 encoding when the file does not exist, as compared to previous node versions.

On a low level, it seems we are not passing the O_CREAT flag to uvlib anymore.

Examples:

In node 16.16.0:

❯ nvm use 16.16
Now using node v16.16.0 (npm v8.11.0)
❯ node
Welcome to Node.js v16.16.0.
Type ".help" for more information.
> fs.writeFileSync('./test.txt', 'test', {encoding: 'utf8'});
undefined
> fs.readFileSync('./test.txt');
<Buffer 74 65 73 74>

In node 21.2.0:

❯ nvm use 21.2
Now using node v21.2.0 (npm v10.2.3)
❯ node
Welcome to Node.js v21.2.0.
Type ".help" for more information.
> fs.writeFileSync('./test.txt', 'test', {encoding: 'utf8'});
undefined
> fs.readFileSync('./test.txt');
<Buffer 74 65 73 74>

In node 21.3.0 (currently latest):

❯ nvm use 21.3
Now using node v21.3.0 (npm v10.2.4)
❯ node
Welcome to Node.js v21.3.0.
Type ".help" for more information.
> fs.writeFileSync('./test.txt', 'test', {encoding: 'utf8'});
Uncaught Error: ENOENT: no such file or directory, open './test.txt'
    at Object.writeFileSync (node:fs:2352:20) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: './test.txt'
}

Currently, a workaround for 21.3.0 is to pass the w flag (which includes O_CREAT) explicitly when calling writeFileSync. e.g:

fs.writeFileSync('./test.txt', 'test', {encoding: 'utf8', flag: 'w'}); --> works
fs.writeFileSync('./test.txt', 'test', {encoding: 'utf8'}); --> does not work

This PR will just set the w flag back as the default value when it is not specified, so its the same behavior from previous node versions.

Fixes https://github.com/nodejs/node/issues/50989

Merge request reports

Loading