denoland/deno · error · Error
No callback function supplied
Error message
No callback function supplied
What it means
fs.readdir(path, [options], callback) resolves its callback from optionsOrCallback (if a function) or maybeCallback; if neither is a function it throws the plain Error 'No callback function supplied' (no code). Note that unlike some fs APIs, path validation happens before this check, so a bad path throws first.
Source
Thrown at ext/node/polyfills/_fs/_fs_readdir.ts:170
export function readdir(
path: string | Buffer | URL,
optionsOrCallback:
| readDirOptions
| string
| readDirCallback
| readDirCallbackDirent,
maybeCallback?: readDirCallback | readDirCallbackDirent,
) {
const callback =
(typeof optionsOrCallback === "function"
? optionsOrCallback
: maybeCallback) as readDirBoth | undefined;
const options = normalizeOptions(
typeof optionsOrCallback === "function" ? null : optionsOrCallback,
);
path = getValidatedPathToString(path);
if (!callback) throw new Error("No callback function supplied");
validateEncoding(options?.encoding);
const { join, relative } = lazyPath();
const result: Array<string | Dirent> = [];
const dirs = [path];
let current: string | undefined;
(async () => {
while ((current = ArrayPrototypeShift(dirs)) !== undefined) {
try {
const entries = await collectReadDir(current);
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
if (options?.recursive && entry.isDirectory) {
ArrayPrototypePush(dirs, join(current, entry.name));
}
View on GitHub (pinned to 89f33cbef2)
Solutions
- Use fs.promises.readdir(path, options) for await-style code
- Otherwise append a callback: fs.readdir(path, (err, files) => { ... })
- Check wrappers forward the callback as the final positional argument
Example fix
// before
fs.readdir(dir, { recursive: true });
// after
const files = await fs.promises.readdir(dir, { recursive: true });
// or
fs.readdir(dir, { recursive: true }, (err, files) => { if (err) throw err; }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof optionsOrCallback !== 'function' && typeof maybeCallback !== 'function') {
throw new Error('readdir requires a callback; use fs.promises.readdir for promises');
} Type guard
const isCallback = (v) => typeof v === 'function';
Prevention
- Prefer fs.promises.readdir in async code
- Keep the callback as the final positional argument in wrappers
- Rely on TypeScript signatures to catch missing callbacks
When it happens
Trigger: fs.readdir('/tmp') with no second argument; fs.readdir('/tmp', { withFileTypes: true }) with options but no callback.
Common situations: Expecting readdir to return entries synchronously or as a promise while using the callback form; refactors between fs.promises.readdir and fs.readdir losing the trailing function.
Related errors
- No callback function supplied
- No callback function supplied
- No callback function supplied
- TypeError [ERR_INVALID_OPT_VALUE_ENCODING]: The value "${enc
- A file exists at the destination: ${destStr}
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/ee547bf958448ca8.
Report an issue: GitHub.