nodejs/node · error

failed to open output file [%s]: %s\n

Error message

failed to open output file [%s]: %s\n

What it means

`OpenOutputFile` failed at the `open()` system call (fd returned < 0). The `open` uses `O_CREAT | O_WRONLY | O_TRUNC` plus `O_EXCL` unless `--force` was passed, meaning it refuses to clobber an existing file by default. The message shows the path and the errno description.

Source

Thrown at deps/brotli/c/tools/brotli.c:806

    fprintf(stderr, "failed to open input file [%s]: %s\n",
            PrintablePath(input_path), strerror(errno));
    return BROTLI_FALSE;
  }
  return BROTLI_TRUE;
}

static BROTLI_BOOL OpenOutputFile(const char* output_path, FILE** f,
                                  BROTLI_BOOL force) {
  int fd;
  *f = NULL;
  if (!output_path) {
    *f = fdopen(MAKE_BINARY(STDOUT_FILENO), "wb");
    return BROTLI_TRUE;
  }
  fd = open(output_path, O_CREAT | (force ? 0 : O_EXCL) | O_WRONLY | O_TRUNC,
            S_IRUSR | S_IWUSR);
  if (fd < 0) {
    fprintf(stderr, "failed to open output file [%s]: %s\n",
            PrintablePath(output_path), strerror(errno));
    return BROTLI_FALSE;
  }
  *f = fdopen(fd, "wb");
  if (!*f) {
    fprintf(stderr, "failed to open output file [%s]: %s\n",
            PrintablePath(output_path), strerror(errno));
    return BROTLI_FALSE;
  }
  return BROTLI_TRUE;
}

static int64_t FileSize(const char* path) {
  FILE* f = fopen(path, "rb");
  int64_t retval;
  if (f == NULL) {
    return -1;
  }

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Add `--force` / `-f` to allow overwriting the existing output file.
  2. Delete or rename the existing output file first.
  3. Verify the output directory exists and is writable.
  4. Use `--output -` to write to stdout if no output file is needed.

Example fix

// before
brotli input.txt  # input.txt.br already exists
// after
brotli -f input.txt
Defensive patterns

Strategy: validation

Validate before calling

#include <unistd.h>
#include <stdbool.h>

bool can_write_output(const char *path, bool force) {
    if (!path) return true; // stdout
    if (!force && access(path, F_OK) == 0) {
        // File exists and --force not set -> O_EXCL will fail
        return false;
    }
    // Check parent dir is writable
    // (simplified; in production extract dirname and check)
    return true;
}

// Before brotli: if (!can_write_output(out, force)) { ... }

Prevention

When it happens

Trigger: The output file already exists and `--force` (`-f`) was not provided, triggering EEXIST via O_EXCL. Alternatively: the parent directory does not exist (ENOENT), write permission denied (EACCES), disk full (ENOSPC at open time on some filesystems), or read-only filesystem (EROFS).

Common situations: Re-running a compress/decompress command without `-f`; piping output into a directory that was never created; running as a different user than the one that owns the existing output file.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/150b1fd31a6a7194. Report an issue: GitHub.