How do you debug incorrect content pages? The debug logs don't show what went wrong

I successfully moved 500+ pages from Jekyll to Hugo.

Beyond those 500+ pages I also have around 300+ draft posts. These drafts are chicken scratch notes with potentially invalid frontmatter or template calls that Jekyll was ok with but not Hugo.

When I add those drafts I get:

Error: error building site: render: failed to render pages: render of "page" failed: "/app/layouts/blog/single.html:3:21": execute of template failed: template: blog/single.html:3:21: executing "main" at <.Fragments.HeadingsMap>: nil pointer evaluating *tableofcontents.Fragments.HeadingsMap

I know it’s one of the draft posts causing this because if I remove all of them then everything works. The problem is I have 317 drafts and I don’t know which one is causing the error. I grepped the drafts for {{ and {{% and removed those cases.

I ran Hugo with --logLevel debug expecting to see which page may have caused the error but it didn’t provide any additional context on the error. The templateMetrics* config options also don’t show which page is causing the error.

Is there a method to narrow down the issue other than manually doing a bi-section search to perform a process of elimination?

What is on line 3 of /layouts/blog/single.html?

{{ range .Fragments.HeadingsMap }} which is part of this loop:

  {{ range .Fragments.HeadingsMap }}
    {{ if (eq .Level 3) }}
      {{ $h3Count = add $h3Count 1 }}
    {{ end }}
  {{ end }}

I use this count to offset a word count value since it was counting these headers as a word due to a render link hook adding a named tag.

Fixing this specific error is easy, I did it in 5 minutes with a bi-section search but more generally it would great if there were a way to see which content file is causing the issue in a layout error. I’ve gotten layout errors multiple times and it’s related to an element that exists (or might be missing) in ~500 posts.

This request has been there a while there are some issues on github and topice here.

How to get the erroring page

Latest issue ive seen: Full path to file should be given in error message · Issue #12693 · gohugoio/hugo · GitHub

1 Like

Oh, nice. I didn’t see that.

I commented there with more details because their issue and this topic’s issue are highly related but there could be an implementation detail difference since there’s no missing file path in my case, it’s missing the entire content file.

Anyhow, I don’t know from the top of my head when/if/should .Fragments is nil, but if you make the template a litte more defensive, e.g.:

 {{ with .Fragments}}
  {{ range .HeadingsMap }}
    {{ if (eq .Level 3) }}
      {{ $h3Count = add $h3Count 1 }}
    {{ end }}
   {{ end }}
  {{ end }}
{{ else }}
// Maybe add a warning with the page/file path.
{{ end }}
1 Like

In this case I want it to be less defensive because if my headers are malformed I want it to fail so I can avoid publishing a page with potentially messed up headers.

The concern here is identifying which one is busted.

Thats exactly the way - add errorf for each with block in its else and it will fail the build

If you use . As a string you know the page

That would require modifying every custom piece of logic to output the page or file in an else right? This is one of about 50 or 60 loops or “potentially failing” pieces of logic. I was hoping this could be solved in one spot instead of manually adding all of that.

Typically when a program fails due to an error, the interpreter or compiler will give you a stack trace so you know what file is acting up. You normally wouldn’t need to write this logic into every area where your code base could potentially fail?

First it seems hard to get that - for some reason I don’t know and I won’t guessing - but here I believe in @bep.

Wrong place for starting a software quality discussion

A foreseen error has to be handled by the programmer with a proper message. In this case It’s the one coding the layout. And yes you should check for possible errors.

Or in short words: you don’t want your calculator to show a stack trace if you try 1/0.

Don’t get me wrong. I would definitely like to have the access to such information like failing page within hugo core

1 Like

@nickjanetakis most of the errors in Hugo have gone through many iterations of careful thought about what to include in them. I have seen your error and similar error thousand times, and the having the page filename in there means

  1. The log gets flooded with errors (for every/most page)
  2. You’re missing out the, in 99% of the cases, most vital part of it: The template file and location (line/col) where you need to fix the issue.

You’re saying that this is a content problem, I’m saying that it’s a template problem (at least mostly).

You’re saying that the log errors are missing some context, I’m saying that this particular error is very well thought out.

We disagree, that’s fine.

I’m with you @bep fot the first paragraph and especially the it is a template problem

But I cannot see the flooding for that fatal errors:

  • hugo terminates at the first error

a template alway fails for specific content. So this would be a very valuable information for the template developer and just one line in output

Error: error building site: render: failed to render pages: render of "page" failed: "/app/layouts/blog/single.html:3:21": 
execute of template failed: template: blog/single.html:3:21: 
executing "main" at <.Fragments.HeadingsMap>: nil pointer evaluating *tableofcontents.Fragments.HeadingsMap

for page content/blog/somepath/somefile.md 

Not saying that this will be easy. Maybe expensive…but imho worthfully.

There are lot of topics and some github issues about that and many developers seem to have their own debugging code for that reason

Keep in mind more and more users are utilising existing templates and have no clue on the layouts.

Not when running the server. Also, Hugo shuts down at the first error, which is different from a kill -9. I’m writing this on a hefty MacBook Pro M1 with 10 CPU cores. With a site with thousands of pages using the faulty single.html template, you can fill the screen with error messages before the process dies.

Hugo drops duplicate error log statements to prevent this.

I’m pretty sure we had the page filename in the error message we discuss in this thread at some point, but people complained that “they couldn’t see the forest for all the trees”, so we removed it to make it less verbose and more to the point.

Thx for the explanation got the flooding point.

I would personally prefer the addional line.

  • take the last error
  • analyse content and template and fix
  • rerun hugo
  • maybe now thausends of errors less
  • if stull errors continue upfront

I admit that depends on the point and the angle you look at it…

That said I’m fine :wink:

1 Like

It’s ok, I see it as a content problem because a content page is the cause of the error. The logic being in a layout file is an implementation / abstraction level detail.

I fully agree with @irkode’s follow up response. There would be no flood of logs here. It’s1 extra line of output during an error which includes the path of the content file / page that is currently causing the error.

I only have 4 cores but I see 1 error message, not 4 of them. I’m at over 800 pages, but the error occurs and halts the process on the first page that causes the error. I’ve never experienced a massive log dump. Occasionally I got Go to panic from something but those are true exceptions.