The "cb" argument must be of type function Received undefined

avatar
Borislav Hadzhiev

Last updated: Apr 5, 2024
3 min

banner

# The "cb" argument must be of type function Received undefined

The Node.js error 'The "cb" argument must be of type function. Received undefined' occurs when you use an asynchronous fs method that expects a callback function as a parameter without providing one.

You can solve the error in multiple ways:

  1. Use the synchronous version of the method, e.g. fs.writeFileSync instead of fs.writeFile
  2. Import fs from fs/promises to use the asynchronous version of the fs method.
  3. Specify the callback function in the call to the fs method.

cb argument must be of type function received undefined

Here is an example of how the error occurs.

index.js
import fs from 'fs'; // ๐Ÿ‘‡๏ธ If you use CommonJS // const fs = require('fs') const fileName = 'example.txt'; // โ›”๏ธ TypeError [ERR_INVALID_ARG_TYPE]: The "cb" argument must be of type function. Received undefined fs.writeFile(fileName, 'bobbyhadz.com');

The fs.writeFile method expects to get called with the following parameters:

  1. The name of the file.
  2. The data you want to write to the file.
  3. A callback function.

We didn't supply the callback function parameter which caused the error.

The parameters will likely be different if you use a different fs method, however, the method takes a callback function that you didn't pass.

You can hover over the method in your IDE to check what the expected parameters are.

One way to solve the error is to pass the callback function in the call to the method.

index.js
// โœ… Works as expected import fs from 'fs'; // ๐Ÿ‘‡๏ธ if you use CommonJS // const fs = require('fs') const fileName = 'example.txt'; fs.writeFile(fileName, 'bobbyhadz.com', err => { if (err) { console.log(err.message); throw err; } console.log('data written to file'); });

We passed a callback function that takes an err parameter, checks if an error occurred and logs a message to the console.

Node.js callback functions always use the error-first approach.

Depending on which fs method you use, the callback function might take a second parameter - the data the method returns.

index.js
import fs from 'fs'; // ๐Ÿ‘‡๏ธ If you use CommonJS // const fs = require('fs') const fileName = 'example.txt'; fs.stat(fileName, (err, stats) => { if (err) { console.log(err.message); throw err; } console.log(stats.size); });

The callback function the fs.stat() method takes has 2 parameters:

  1. An error (if one occurred).
  2. A stats object for the specified file.

# Using the synchronous version of the method to solve the error

The callback-style syntax from the previous subheading is asynchronous.

You can also use the synchronous version of the fs method to resolve the error.

index.js
import fs from 'fs'; // ๐Ÿ‘‡๏ธ If you use CommonJS // const fs = require('fs') const fileName = 'example.txt'; try { fs.writeFileSync(fileName, 'bobbyhadz.com'); console.log('Data written to file'); } catch (err) { console.log(err.message); }

Notice that we used the fs.writeFileSync() method instead of fs.writeFile.

The Sync suffix indicates that the method is synchronous and doesn't take a callback function parameter.

Most fs methods have a synchronous equivalent, e.g. fs.stat() (asynchronous) and fs.statSync() (synchronous).

# Using the fsPromises version of the method to resolve the error

You can also use the fsPromises version of the fs method to resolve the error.

index.js
import fsPromises from 'fs/promises'; // ๐Ÿ‘‡๏ธ if you use CommonJS // const fsPromises = require('fs/promises') const fileName = 'example.txt'; try { await fsPromises.writeFile(fileName, 'bobbyhadz.com'); console.log('Data written to file'); } catch (err) { console.log(err.message); }

Notice that we now import fsPromises from fs/promises instead of fs from fs.

The fsPromises methods are asynchronous and promisified (they return a Promise).

You can use the more modern and intuitive async/await syntax.

The example assumes that your environment supports top-level await.

Alternatively, you can wrap the code in an async function.

index.js
import fsPromises from 'fs/promises'; // ๐Ÿ‘‡๏ธ If you use CommonJS // const fsPromises = require('fs/promises') async function example(fileName) { try { await fsPromises.writeFile(fileName, 'bobbyhadz.com'); console.log('Data written to file'); } catch (err) { console.log(err.message); } } const fileName = 'example.txt'; example(fileName).then(() => { console.log('This runs after the Promise has resolved'); });

You can use the .then syntax if you need to run some code after the Promise from the async function has been resolved.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev