oven-sh/bun · error · Error

Failed to write file

Error message

Failed to write file ${file}

What it means

writeIfNotChanged writes generated content, then reads the file back and requires byte-for-byte equality. The helper already retries once after mkdir-ing the parent directory, so this error means the write silently failed or the file on disk does not match what was written.

Solutions

  1. Check disk space and write permissions on the output directory (df -h, ls -ld), then rerun the build.
  2. Make sure the output path is a file location, not an existing directory, and that no symlink loop or case-insensitive collision shadows it.
  3. Exclude build output directories from antivirus/sync tools, then rebuild.
Defensive patterns

Strategy: retry

Validate before calling

import fs from "node:fs";
function canWrite(file: string) {
  try {
    fs.accessSync(file.endsWith("/") ? file : fs.dirnameSync?.(file) ?? ".", fs.constants.W_OK);
    fs.statSync(file);
    return !fs.statSync(file).isDirectory();
  } catch {
    return false;
  }
}

Try / catch

try {
  writeIfNotChanged(outFile, contents);
} catch (e) {
  if (process.platform === "win32" && (e as NodeJS.ErrnoException).code === "EPERM") {
    fs.rmSync(outFile, { force: true });
    writeIfNotChanged(outFile, contents); // single retry after clearing the blocker
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Out-of-space disk filling during write, a read-only or permission-denied directory where writeFileSync appears to succeed, the target path existing as a directory, or an external process (antivirus, sync client) rewriting the file between write and read-back.

Common situations: Full disk / full Docker volume during `bun run build`; building into a checkout owned by another user; case-insensitive filesystem collisions; cloud-sync folders normalizing file content.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/d5272f38d2002573. Report an issue: GitHub.

Appendix: source

Thrown at src/codegen/helpers.ts:60

  if (Array.isArray(contents)) contents = contents.join("");
  contents = contents.replaceAll("\r\n", "\n").trim() + "\n";

  try {
    const oldContents = fs.readFileSync(file, "utf8");
    if (oldContents === contents) {
      return;
    }
  } catch (e) {}

  try {
    fs.writeFileSync(file, contents);
  } catch (error) {
    fs.mkdirSync(path.dirname(file), { recursive: true });
    fs.writeFileSync(file, contents);
  }

  if (fs.readFileSync(file, "utf8") !== contents) {
    throw new Error(`Failed to write file ${file}`);
  }
}

export function writeIfNotChangedBinary(file: string, contents: Buffer) {
  try {
    if (fs.readFileSync(file).equals(contents)) return;
  } catch {}
  try {
    fs.writeFileSync(file, contents);
  } catch {
    fs.mkdirSync(path.dirname(file), { recursive: true });
    fs.writeFileSync(file, contents);
  }
}

export function readdirRecursiveWithExclusionsAndExtensionsSync(
  dir: string,
  exclusions: string[],

View on GitHub (pinned to 8c5296ac45)