Code review example: Wrong API flavor: awaiting callback-style fs.stat crashes every call in Node

Retired from the DiffDojo practice pool in October 2026; the review below is the canonical answer. An AI wrote this pull request for the task underneath. Read the diff and decide what you would say before you scroll to the review.

Node · Hallucinated APIs & dependencies · intermediate

The task

Load the export directory size

  1. Add a helper that returns the size (in bytes) of a file in the exports directory.
  2. Use the fs module's stat call.
  3. Return the size as a number; let errors propagate to the caller.

Adds a small helper around fs.stat to read a file's size before we stream it. Awaits the stat call and returns the size in bytes.

Runs inside the export service on Node 20; the project has no custom fs wrappers.

The diff

src/exports/fileSize.js+8
1+ const fs = require('fs');
2+
3+ async function fileSize(path) {
4+ const stats = await fs.stat(path);
5+ return stats.size;
6+ }
7+
8+ module.exports = { fileSize };

The review

Issue 1: Wrong API flavor: awaiting callback-style fs.stat crashes every call

src/exports/fileSize.js, lines 1, 4

  1. require('fs').stat is the callback-style function. It expects (path, callback); the promise-based API is a different import, require('fs/promises').stat (or fs.promises.stat).
  2. Called without a callback, modern Node throws immediately, TypeError [ERR_INVALID_ARG_TYPE]: The "cb" argument must be of type function. Every call crashes before any file is examined; the helper never returns a size.
  3. Even the error is wrong. The caller sees a callback-signature TypeError, not the fs error the requirement wants propagated.
  4. The call site reads idiomatically. await fs.stat(...) is exactly how the promise version is used, which is why this slips through review, only the import line gives it away.

The fix: import from fs/promises.

The fix

const fs = require('fs/promises');

async function fileSize(path) {
  const stats = await fs.stat(path);
  return stats.size;
}

module.exports = { fileSize };

Why it matters

An await on an fs call → ask: "is the import fs/promises, or the callback-style fs?"

Real-world stakes: Node ships two flavors of the same API, and LLMs regularly stitch them together, a promise-style call site with the callback-style import. Everything reads correct line by line; the mismatch only exists across two lines, and no linter in a plain-JS project objects. The first real call throws a confusing callback-signature TypeError from deep inside fs, and whoever debugs it starts from the wrong end, because the call site looks exactly like correct promise code.

Read more: fs promises vs callback stat node, await fs.stat returns undefined, require fs/promises, node util.promisify fs

The verdict

Request changes. Wrong API flavor: awaiting callback-style fs.stat crashes every call

Try a live one

Node PRs you have not seen the answer to.

Leave inline comments and a verdict, then see what you caught. Free, no signup.

Review a Node PR →

How to review Node code · All code review examples