Susan Harkins (398) [Avatar] Offline
Please post errors found in the published version of Node.js in Action, Second Edition here. If necessary, we'll publish a comprehensive list for everyone's convenience. Thank you!

Susan Harkins
Errata Editor
303763 (9) [Avatar] Offline
Following are a few items that may need to be addressed:

- Page 102, Section 5.9

This really does not reflect Loopback 3.0. Now you install “loopback-cli” with nom Instead of “strongloop”. Also the command is now “lb” instead of “slc”. So it’s also “lb:model”, etc.

- Page 109, section 6.1.1

Express is not actually built with Connect any more. This used to be the case before Express 4. However it still supports middleware using Connect conventions.

-Page 119, figure 6.6

The directory was not updated from Jade to Pug.
289422 (4) [Avatar] Offline
Incorrect code. Missing `(err, result)` from anonymous function declaration.
Page 206 - Listein 8.3.

`, () => {
if (err) throw err;
const id = result.rows[0].id;
console.log('Inserted row with id %s', id);
289422 (4) [Avatar] Offline
Subject - specifying tag content - Pug

Suggested way is not working for current Pug version.

If the HTML tag, such as the style and script tags, accepts only text (meaning it
doesn’t allow nested HTML elements), then the | characters can be left out entirely, as
the following example shows:
h1 {
font-size: 6em;
color: #9DFF0C;

Current working way - using dot at the end of the tag:

h1 {
font-size: 6em;
color: #9DFF0C;
289422 (4) [Avatar] Offline
Chapter 12 - Listing 12.2 - Electron

Using the remote library is dated.

let remote = require('remote')

Instead this is what is working now:

let { remote } = require('electron');
233628 (1) [Avatar] Offline
Chapter 12. Conquering the desktop with Electron

12.3.2 Installing the Dependencies

.babelrc file is missing a setting:

"plugins": [
"presets": ["es2015"]
338322 (1) [Avatar] Offline
Chapter 3.1, Pg. 52 under "A Simple Server"

There is a small error in the app.listen portion of the example code -- there needs to be an opening curly brace in the anonymous function declaration and a closing parentheses at the end of the block before the semicolon:

const express = require('express');
const app = express();

const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('Hello World');

app.listen(port, () =>
  console.log(`Express web app available at localhost: ${port}`);


last section should be:
app.listen(port, () => {
  console.log(`Express web app available at localhost: ${port}`);
alex.young (10) [Avatar] Offline
Thanks for the errors and changes everyone has suggested so far. I'm going to work through them and start building up a proper errata over the next few days.

If there are any other issues just post to this thread.
Susan Harkins (398) [Avatar] Offline
An updated errata list for Node.js in Action, Second Edition is available at Thanks!

Susan Harkins
Errata Editor
Manning Publications
315401 (10) [Avatar] Offline
After listing 6.10 it says "Now when you use a browser to access /post on your application, you’ll be able to add entries."

Actually, the app won't even start until completing the section on the next page titled "ADDING ENTRY-RELATED ROUTES".

app.get('/post', entries.form);

ReferenceError: entries is not defined
315401 (10) [Avatar] Offline
The start of section 6.2.4 promises to "Implement pagination", but pagination is only partly implemented later in section 6.2.9, and never in the UI as in the "full-app" in the code repo.
315401 (10) [Avatar] Offline
Needless confusion in Chapter 6. Is it a "post" or is it an "entry"? Pick one: entry

For example: the entries route (at /post (singular)) uses the post.ejs form to create an "entry", but the api uses /api/entries (plural) to create entries
315401 (10) [Avatar] Offline
section 6.2.4 (pp 132-134) makes use of res.error which isn't defined until section 6.2.6 (p 143)
315401 (10) [Avatar] Offline
Listing 6.18

const User = require('./models/user');

This line redefines User; is an error.
315401 (10) [Avatar] Offline
Section 6.2.6, pp 142-143

The res.message function provides a way to add messages to a session variable from
any Express request. The express.response object is the prototype that Express
uses for the response objects. Adding properties to this object means they’ll then be
available to all middleware and routes alike. In the preceding snippet,
express.response is assigned to a variable named res to make it easier to add
properties on the object and to improve readability.

The code this paragraph refers to is not present; this paragraph is the only appearance of express.response in the whole book.
315401 (10) [Avatar] Offline
Snippet on page 144 includes

but methodOverride is only covered in Appendix C.

This code snippet on page 147 was already done at the start of section 6.2.7.

const login = require('./routes/login');
app.get('/logout', login.logout);

Listing 6.29 should include the prior edits to app.use(session(...))

  secret: 'secret',
  resave: false,
  saveUninitialized: true

Same listing, the line

is explained nowhere.

Section 6.2.9 TESTING USER DATA RETRIEVAL on page 152: the curl command will succeed no matter what you send for user:pass, because authentication is not actually enabled.

In the full-app code repo, api.auth is different
exports.auth = (req, res, next) => {
  req.remoteUser = auth(req);

but also doesn't prevent unauthorized access.

Testing api posting later results in redirect to /, because of no remoteUser, but the post is created anyway.

The fail occurs because when User.authenticate is called with an unknown user, the callback is called without args (because !, and so both user and err are undefined. :-{ The root cause is further up the chain, probably somewhat because getId never triggers an error.

p 155, TESTING THE ENTRIES ROUTE fails because page() was never required in app.js

532364 (1) [Avatar] Offline
To perform Basic authentication, install the basic-auth module: npm install --save basic-auth. Next, create the ./routes/api.js file, and require both Express and the user model, as shown in the following snippet. The basic-auth package accepts a function to perform the authentication, taking the function signature (username, password, callback). Your User.authenticate method is a perfect fit:

This doesn't make any sense since the basic-auth package doesn't accept a function to perform the authentication. I assume that req.remoteUser was intended to be checked in the api.user method at some point to determine whether the User should be fetched at all or if a 401/403 should be sent instead.

if (!req.remoteUser) return res.sendStatus(401);

Adding this line to api.user returns something along the lines of what we're looking for I think:

exports.user = (req, res, next) => {
    if (!req.remoteUser) return res.sendStatus(401);
    User.get(, (err, user) => {
        if (err) return next(err);
        if (! return res.sendStatus(404);


539022 (2) [Avatar] Offline
page 291 --> memory leak

this.handleResult.bind(this) === this.handleResult.bind(this) // output false, because bind will create new function all the time

Taking it into account, there is no use in removing handleResult in componentWillUnmount method, since we try to remove something new from listener.

We should create handler in constructor and reuse it in componentWillUnmount to free resources

211085 (2) [Avatar] Offline
RE: Pagination example in Chapter 6 - I'm not sure if this works as described.

Given the following in app.js:

app.get('/api/entries/:page?, page(Entry.count), api.entries);

The text instructs to
use the query-string ?page=N value
which would suggest a call similar to this:

curl http://foo:bar@

However, if you look at the corresponding middleware code in page.js:

let page = Math.max(parseInt( || "1", 10), 1) -1;

You see that the code is looking for which will be undefined since that won't be populated given a query string. In order to use a query string the code should look at to get the value.

If you want to continue to use You could modify the call to:

curl http://foo:bar@ which would work

Perhaps one of the authors saw the '?' and assumed it was a query string instead defining an optional parameter, (or maybe I'm missing something)
384347 (2) [Avatar] Offline
Errata in Node.js in Action, Listing 6.18
315401 wrote:Listing 6.18

const User = require('./models/user');

This line redefines User; is an error.

Easier to put code in a separate file in models folder and execute with node.
558379 (7) [Avatar] Offline
Appendix C

Page 312, Section C.1

"This section cover four modules .." followed by a list of 3 modules instead of 4.

Suggested Correction: The content is correct though, there is 4th module compression which is not included in the list

Page 327, Section C.2.1

Subheading "LOGGER OPTIONS: STREAM, IMMEDIATE, AND BUFFER", but no mention of Buffer option anywhere in text

Suggested Correction: From the content of Node.js in Action, First Edition, there is a paragraph mentioned of Buffer. Perhaps, it is not copied over in the 2nd edition
457184 (1) [Avatar] Offline
"10.3.3. Hosting static files and proxying"

On the Nginx configuration listing (10.4) epub format, the clustering sample from listing 10.3 is repeated.
In the pdf version this error is not present.

João Antunes