Fix the 'cb.apply is not a function' error in GitBook

By

How I once fixed cb.apply is not a function from graceful-fs under gitbook-cli, and why Honkit is the better path for Markdown books now.

~~~

I used to use gitbook-cli, a little Node.js tool to generate an ebook from a set of markdown files.

gitbook-cli is unmaintained. Its last release was in 2017. To turn Markdown into a PDF or EPUB today, use Honkit, a maintained fork (npx honkit pdf ./ ./book.pdf). I walk through that workflow in How to create ebooks from Markdown. Prefer that over patching node_modules.

The rest of this post is the historical debugging story, in case you still hit the same graceful-fs error on an old install.

I was trying to generate a PDF, running gitbook pdf ., when I got a really weird error:

  ebook git:(master)  gitbook pdf .
/usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287
      if (cb) cb.apply(this, arguments)
                 ^

TypeError: cb.apply is not a function
    at /usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287:18

cb.apply is not a function. What does this even mean? And most importantly, why do I have this error now? I didn’t update the gitbook package recently, and I didn’t… Oh I think I updated the Node.js version I run. But I have no idea why this should be the problem. Maybe it is.

Anyway.. the error comes from the /usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js file. This is the graceful-fs npm package, a “drop-in replacement for the built-in Node.js fs module, making various improvements”.

One of those improvements seemed to break my workflow that day!

I didn’t have a lot of time free to find out why my Node.js version gave problems with this application I didn’t create and this library.

I opened the file /usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js, where the error comes from.

Here’s the function that gave the problem:

function statFix (orig) {
  if (!orig) return orig
  // Older versions of Node erroneously returned signed integers for
  // uid + gid.
  return function (target, cb) {
    return orig.call(fs, target, function (er, stats) {
      if (!stats) return cb.apply(this, arguments)
      if (stats.uid < 0) stats.uid += 0x100000000
      if (stats.gid < 0) stats.gid += 0x100000000
      if (cb) cb.apply(this, arguments)
    })
  }
}

This seems to fix something in older version of Node.js.. it shouldn’t be needed for me.

I see it’s being used in lines 62-64 of the same file:

fs.stat = statFix(fs.stat)
fs.fstat = statFix(fs.fstat)
fs.lstat = statFix(fs.lstat)

I commented out those lines:

// fs.stat = statFix(fs.stat)
// fs.fstat = statFix(fs.fstat)
// fs.lstat = statFix(fs.lstat)

and everything worked fine, I was able to run the gitbook command again, and I got my nice PDF.

That hack unblocked me once. Don’t build a workflow on it. Switch to Honkit (or another maintained Markdown book tool) and leave gitbook-cli behind.

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about js: