{"record":{"id":"9defa08fcb461895","repo":"denoland/deno","slug":"no-callback-function-supplied","errorCode":null,"errorMessage":"No callback function supplied","messagePattern":"No callback function supplied","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_fs/_fs_fstat.ts","lineNumber":63,"sourceCode":"    isFifo: stat.isFifo,\n    isSocket: stat.isSocket,\n  };\n}\n\nfunction fstat(\n  fd,\n  optionsOrCallback,\n  maybeCallback,\n) {\n  fd = lazyFsUtils().getValidatedFd(fd);\n  const callback = typeof optionsOrCallback === \"function\"\n    ? optionsOrCallback\n    : maybeCallback;\n  const options = typeof optionsOrCallback === \"object\"\n    ? optionsOrCallback\n    : { bigint: false };\n\n  if (!callback) throw new Error(\"No callback function supplied\");\n\n  PromisePrototypeThen(\n    op_node_fs_fstat(fd),\n    (stat) =>\n      callback(\n        null,\n        lazyStatUtils().CFISBIS(nodeFsStatToFileInfo(stat), options.bigint),\n      ),\n    (err) => callback(denoErrorToNodeError(err, { syscall: \"fstat\" })),\n  );\n}\n\nfunction fstatSync(\n  fd,\n  options,\n) {\n  fd = lazyFsUtils().getValidatedFd(fd);\n  try {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/_fs/_fs_fstat.ts#L45-L81","documentation":"The callback form of fs.fstat expects (fd[, options], callback). When the callback slot is not a function - typically options passed as the second argument with no third argument - it throws the plain Error 'No callback function supplied' before any I/O happens.","triggerScenarios":"fs.fstat(fd, { bigint: true }) with the callback forgotten; fs.fstat(fd) with neither options nor callback; options and callback supplied in the wrong order.","commonSituations":"Mechanical sync-to-async conversion that left options in the callback position; refactors that dropped the trailing callback; passing a variable that is undefined at runtime.","solutions":["Add the callback: fs.fstat(fd, { bigint: true }, (err, stat) => ...)","Use fs.promises.fstat(fd, { bigint: true }) with await","Use fs.fstatSync(fd, { bigint: true }) for synchronous code"],"exampleFix":"// before\nfs.fstat(fd, { bigint: true }); // Error: No callback function supplied\n\n// after\nimport { fstat } from \"node:fs/promises\";\nconst stats = await fstat(fd, { bigint: true });","handlingStrategy":"type-guard","validationCode":"function fstatArgs(\n  fd: number,\n  optionsOrCallback?: object | ((err: Error | null, stats?: unknown) => void),\n  maybeCallback?: (err: Error | null, stats?: unknown) => void,\n) {\n  const callback = typeof optionsOrCallback === \"function\"\n    ? optionsOrCallback\n    : maybeCallback;\n  const options = typeof optionsOrCallback === \"object\" ? optionsOrCallback : {};\n  if (typeof callback !== \"function\") {\n    throw new Error(\"fs.fstat requires a callback (or use fs.promises.fstat / fs.fstatSync)\");\n  }\n  return { fd, options, callback };\n}","typeGuard":"function isCallback(v: unknown): v is (...args: unknown[]) => void {\n  return typeof v === \"function\";\n}","tryCatchPattern":null,"preventionTips":["Prefer fs.promises.fstat in modern async code - no callback slot to forget","When converting sync code, replace options-only calls with the *Sync or promises variant deliberately","Lint for fs.* calls whose last argument is an object literal (a common dropped-callback smell)"],"tags":["fs","node-compat","callback","validation","fstat"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}