oven-sh/bun · error · Error

file did not exist after write: ${outputPath}

Error message

file did not exist after write: ${outputPath}

What it means

Thrown by Bun's builtin-module codegen (src/codegen/bundle-modules.ts) when a transpiled module file is written to the temp output directory but immediately fails an fs.existsSync check. The write() promise resolved, so the filesystem silently dropped or hid the file — this is an environment-level write-visibility failure, not a code bug. The script treats it as fatal for that module, but an outer retry(3, ...) path (error 321) attempts recovery.

Source

Thrown at src/codegen/bundle-modules.ts:187

      },
    );
    if (!exportOptimization) {
      fileToTranspile = `var $;` + fileToTranspile.replaceAll("__intrinsic__exports", "$");
    }
    const outputPath = path.join(TMP_DIR, moduleList[i].slice(0, -3) + ".ts");

    await mkdir(path.dirname(outputPath), { recursive: true });
    if (!fs.existsSync(path.dirname(outputPath))) {
      verbose("directory did not exist after mkdir twice:", path.dirname(outputPath));
    }

    fileToTranspile = "// @ts-nocheck\n" + fileToTranspile;

    try {
      await writeFile(outputPath, fileToTranspile);
      if (!fs.existsSync(outputPath)) {
        verbose("file did not exist after write:", outputPath);
        throw new Error("file did not exist after write: " + outputPath);
      }
      verbose("wrote to", outputPath, "successfully");
    } catch {
      await retry(3, async () => {
        await mkdir(path.dirname(outputPath), { recursive: true });
        await writeFile(outputPath, fileToTranspile);
        if (!fs.existsSync(outputPath)) {
          verbose("file did not exist after write:", outputPath);
          throw new Error("file did not exist after write: " + outputPath);
        }
        verbose("wrote to", outputPath, "successfully later");
      });
    }
    bundledEntryPoints.push(outputPath);
  } catch (error) {
    console.error(error);
    console.error(`While processing: ${moduleList[i]}`);
    process.exit(1);

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Re-run the build once — the immediate existsSync failure plus 3 retries all failing usually means a persistent cause, but transient AV locks do clear
  2. Check free space and write permissions on the temp/build directory (df, and touch a file in the same dir)
  3. Move the repository out of OneDrive/Dropbox-synced folders, or add the repo and temp dir to antivirus exclusions
  4. On Windows, shorten the workspace path or enable long-path support (registry LongPathsEnabled) so TMP_DIR + module path stays under MAX_PATH
Defensive patterns

Strategy: retry

Validate before calling

// preflight before running codegen: prove the temp dir is writable
import fs from "node:fs";
import os from "node:os";
const dir = fs.mkdtempSync(`${os.tmpdir()}/codegen-preflight-`);
fs.writeFileSync(`${dir}/probe.js`, "probe");
fs.rmSync(dir, { recursive: true });
console.log("temp dir writable");

Try / catch

// the script already retries; at the outer build level treat as transient once
try {
  await runCodegen();
} catch (e) {
  if (String(e.message).startsWith("file did not exist after write")) {
    await runCodegen(); // one full retry; a second failure means a persistent FS problem
  } else throw e;
}

Prevention

When it happens

Trigger: Running `bun run build` / bundle-modules codegen when the temp output directory sits on a slow or filtered filesystem: antivirus/EDR locking freshly written files, OneDrive/Dropbox sync folders removing or delaying files, disk-full or quota exhaustion, or Windows MAX_PATH overflows from the deep TMP_DIR/modules_out nesting.

Common situations: Windows dev machines with Defender real-time scanning the repo; cloned repos inside cloud-synced folders; CI runners with a nearly full disk; Docker containers with a small tmpfs /tmp.

Related errors


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