Blog2020 ≫ Metalsmith - Cannot read property 'toString' of undefined

This is an annoying error I get sometimes and it's really hard to track down where or what it is. Pleased to say I have solved it though. Look at the error output we get first:

Template render error: (unknown path) [Line 3, Column 27]
  TypeError: Cannot read property 'toString' of undefined
    at Object._prettifyError (node_modules/nunjucks/src/lib.js:36:11)
    at node_modules/nunjucks/src/environment.js:561:19
    at Template.root [as rootRenderFunc] (eval at _compile (node_modules/nunjucks/src/environment.js:631:18), <anonymous>:318:3)
    at Template.render (node_modules/nunjucks/src/environment.js:550:10)
    at Environment.renderString (node_modules/nunjucks/src/environment.js:378:17)
    at Object.renderString (node_modules/nunjucks/index.js:99:14)
    at node_modules/consolidate/lib/consolidate.js:1174:11
    at node_modules/consolidate/lib/consolidate.js:144:5
    at Promise._execute (node_modules/bluebird/js/release/debuggability.js:384:9)
    at Promise._resolveFromExecutor (node_modules/bluebird/js/release/promise.js:518:18)
    at new Promise (node_modules/bluebird/js/release/promise.js:103:10)
    at promisify (node_modules/consolidate/lib/consolidate.js:137:10)
    at exports.nunjucks.render (node_modules/consolidate/lib/consolidate.js:1114:10)
    at convert (node_modules/metalsmith-in-place/lib/index.js:123:7)
    at node_modules/metalsmith-in-place/node_modules/async/lib/async.js:181:20
    at Object.async.forEachOf.async.eachOf (node_modules/metalsmith-in-place/node_modules/async/lib/async.js:233:13)

The error must be caused by some content as that's what I've just changed, but what content? If I've only added one file then it's easy but when I've been bulk editing loads of content on my metalsmith static site then what?

Turns out each time it's because I've failed to close the brackets on the tags: line in my frontmatter... so I had something like

title: My new post
tags: [foo, bar

instead of

title: My new post
tags: [foo, bar]

Easy when you know what to look for... If you have a lot of content and are not sure, you could:

grep -r 'tags:' src/content/ | grep -v \]

and that will find all the lines that have tags: but do not have a closing bracket. We use the -v to mean "do not match" and you probably don't need to escape the closing bracket like that.

UPDATE: There's another thing that can cause this and that's if you have duplicate keys in your frontmatter at the top of your content... So if you have something like this, it's also going to cause the same error.

  ---
  title: "Metalsmith - Cannot read property 'toString' of undefined"
  date: 2020-10-14 11:39:52
  layout: post.html
  layout: post.html
  tags: [metalsmith, error, static site, grep, bash]
  ---
  This is an annoying error...
⬅️ :: ➡️

Paul Clarke's blog - I live in Hythe in the far South. Married + father to 2, I'm a full stack web engineer, + I do js / Node, some ruby, other languages etc. I like pubbing, parkrun, eating, home automation + other diy jiggery-pokery, history, genealogy, TV, squirrels, pirates, lego, and TIME TRAVEL.