11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.33k stars 495 forks source link

Trouble finding the source of a "Having trouble writing template: false" issue #1696

Open nhoizey opened 3 years ago

nhoizey commented 3 years ago

Describe the bug

I'm trying to manage drafts in my Eleventy project, and not including them in a production build.

My _data/eleventyComputed.js file contains this (and much much more):

module.exports = {
  permalink: (data) =>
    data.layout === 'draft' && process.env.NODE_ENV === 'production'
      ? false
      : data.permalink,
};

I've checked in a reduced test case that my drafts collection is there in development mode but empty in production mode, and setting permalink to false this way works, no page is created from the draft Markdown files.

However, with a production build, I get a Having trouble writing template: false error. There is also a TypeError: The "path" argument must be of type string. Received type boolean (false) error, probably related.

I've spent a few hours on this already, and I can't find where this error comes from with the error logs. 🤷‍♂️

Here's the detailed error in debug mode ``` Eleventy:EleventyErrorHandler Error writing templates: +0ms Eleventy:EleventyErrorHandler Having trouble writing template: false Eleventy:EleventyErrorHandler Eleventy:EleventyErrorHandler `TemplateWriterWriteError` was thrown +0ms Eleventy:EleventyErrorHandler (error stack): TemplateWriterWriteError: Having trouble writing template: false Eleventy:EleventyErrorHandler at /path/to/project/node_modules/@11ty/eleventy/src/TemplateWriter.js:216:15 Eleventy:EleventyErrorHandler at processTicksAndRejections (internal/process/task_queues.js:93:5) Eleventy:EleventyErrorHandler at async Promise.all (index 43) Eleventy:EleventyErrorHandler at async Eleventy.write (/path/to/project/node_modules/@11ty/eleventy/src/Eleventy.js:743:13) +0ms Eleventy:EleventyErrorHandler (./src/_layouts/default.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/head.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/components/google-analytics.njk) Eleventy:EleventyErrorHandler TypeError: The "path" argument must be of type string. Received type boolean (false) Eleventy:EleventyErrorHandler Eleventy:EleventyErrorHandler `Template render error` was thrown: +0ms Eleventy:EleventyErrorHandler (error stack): Template render error: (./src/_layouts/default.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/head.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/components/google-analytics.njk) Eleventy:EleventyErrorHandler TypeError: The "path" argument must be of type string. Received type boolean (false) Eleventy:EleventyErrorHandler at Object._prettifyError (/path/to/project/node_modules/nunjucks/src/lib.js:36:11) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/nunjucks/src/environment.js:561:19 Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :30:11) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/nunjucks/src/environment.js:569:11 Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :87:12) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/nunjucks/src/environment.js:569:11 Eleventy:EleventyErrorHandler at Template.root [as rootRenderFunc] (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :22:3) Eleventy:EleventyErrorHandler at Template.render (/path/to/project/node_modules/nunjucks/src/environment.js:550:10) Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :86:10) Eleventy:EleventyErrorHandler at fn (/path/to/project/node_modules/a-sync-waterfall/index.js:26:24) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:66:22 Eleventy:EleventyErrorHandler at executeSync (/path/to/project/node_modules/a-sync-waterfall/index.js:8:15) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:65:11 Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :82:1) Eleventy:EleventyErrorHandler at Environment.getTemplate (/path/to/project/node_modules/nunjucks/src/environment.js:277:9) Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :80:5) Eleventy:EleventyErrorHandler at fn (/path/to/project/node_modules/a-sync-waterfall/index.js:26:24) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:66:22 Eleventy:EleventyErrorHandler at executeSync (/path/to/project/node_modules/a-sync-waterfall/index.js:8:15) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:65:11 Eleventy:EleventyErrorHandler at waterfall (/path/to/project/node_modules/a-sync-waterfall/index.js:71:38) Eleventy:EleventyErrorHandler at Environment.waterfall (/path/to/project/node_modules/nunjucks/src/environment.js:382:12) +0ms Eleventy:EleventyErrorHandler Problem writing Eleventy templates: +52ms Eleventy:EleventyErrorHandler Having trouble writing template: false Eleventy:EleventyErrorHandler Eleventy:EleventyErrorHandler `TemplateWriterWriteError` was thrown +0ms Eleventy:EleventyErrorHandler (error stack): TemplateWriterWriteError: Having trouble writing template: false Eleventy:EleventyErrorHandler at /path/to/project/node_modules/@11ty/eleventy/src/TemplateWriter.js:216:15 Eleventy:EleventyErrorHandler at processTicksAndRejections (internal/process/task_queues.js:93:5) Eleventy:EleventyErrorHandler at async Promise.all (index 43) Eleventy:EleventyErrorHandler at async Eleventy.write (/path/to/project/node_modules/@11ty/eleventy/src/Eleventy.js:743:13) +0ms Eleventy:EleventyErrorHandler (./src/_layouts/default.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/head.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/components/google-analytics.njk) Eleventy:EleventyErrorHandler TypeError: The "path" argument must be of type string. Received type boolean (false) Eleventy:EleventyErrorHandler Eleventy:EleventyErrorHandler `Template render error` was thrown: +0ms Eleventy:EleventyErrorHandler (error stack): Template render error: (./src/_layouts/default.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/head.njk) Eleventy:EleventyErrorHandler Template render error: (/path/to/project/src/_includes/components/google-analytics.njk) Eleventy:EleventyErrorHandler TypeError: The "path" argument must be of type string. Received type boolean (false) Eleventy:EleventyErrorHandler at Object._prettifyError (/path/to/project/node_modules/nunjucks/src/lib.js:36:11) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/nunjucks/src/environment.js:561:19 Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :30:11) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/nunjucks/src/environment.js:569:11 Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :87:12) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/nunjucks/src/environment.js:569:11 Eleventy:EleventyErrorHandler at Template.root [as rootRenderFunc] (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :22:3) Eleventy:EleventyErrorHandler at Template.render (/path/to/project/node_modules/nunjucks/src/environment.js:550:10) Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :86:10) Eleventy:EleventyErrorHandler at fn (/path/to/project/node_modules/a-sync-waterfall/index.js:26:24) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:66:22 Eleventy:EleventyErrorHandler at executeSync (/path/to/project/node_modules/a-sync-waterfall/index.js:8:15) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:65:11 Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :82:1) Eleventy:EleventyErrorHandler at Environment.getTemplate (/path/to/project/node_modules/nunjucks/src/environment.js:277:9) Eleventy:EleventyErrorHandler at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:631:18), :80:5) Eleventy:EleventyErrorHandler at fn (/path/to/project/node_modules/a-sync-waterfall/index.js:26:24) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:66:22 Eleventy:EleventyErrorHandler at executeSync (/path/to/project/node_modules/a-sync-waterfall/index.js:8:15) Eleventy:EleventyErrorHandler at /path/to/project/node_modules/a-sync-waterfall/index.js:65:11 Eleventy:EleventyErrorHandler at waterfall (/path/to/project/node_modules/a-sync-waterfall/index.js:71:38) Eleventy:EleventyErrorHandler at Environment.waterfall (/path/to/project/node_modules/nunjucks/src/environment.js:382:12) +0ms ```

I might have issues in Nunjucks filters or elsewhere, but I don't know how to target the error with these logs.

Environment:

nhoizey commented 3 years ago

I'm not sure this is related to #1258

pdehaan commented 3 years ago

@nhoizey Not sure I'm able to reproduce on a simpler test case (assuming I did the same general logic as your templates): https://github.com/pdehaan/11ty-permalink-false-computed

If you run npm run build it should write all 4 pages. If you run npm run build:prod it should only write 3 pages, since "src/pages/two.njk" is a draft.

Eleventy 0.11.1 on macOS 10.15.7.

solution-loisir commented 3 years ago

Hi @nhoizey, I had a similar issue today with permalink: false triggering error. My problem is that I had an addTransform() trying to consume a false template. I had to add an if condition so to ensure that function was only consuming true values. Based on your error, it looks like some function in the chain is expecting a string, but it's receiving your false template instead.

nhoizey commented 3 years ago

@pdehaan that's what I managed to do on a reduced test case also, the issue is elsewhere.

@solution-loisir I tried without any transform, and I still get the issue. I try every function that should receive a string parameter to check if a false comes in, but I couldn't find any yet.

I really wish Eleventy debug logs would help pinpoint the actual issue… 😅

pdehaan commented 3 years ago

OK, so before I re-re-forget... I was able to get your site building, but ONLY if I was in NODE_ENV=development and not in NODE_ENV=production; so I believe this has something to do with one of your production-only code paths. (Not super helpful)

So with a bit of git grep "production" trial-and-error-and-error, I managed to track it down to the following two snippets. Possibly combined causing issues, possibly unrelated to each other... But something in these lines of code seems to be the root cause:

diff --git a/src/_11ty/shortcodes/include_raw.js b/src/_11ty/shortcodes/include_raw.js
index df444e8e..f0319b0c 100644
--- a/src/_11ty/shortcodes/include_raw.js
+++ b/src/_11ty/shortcodes/include_raw.js
@@ -6,12 +6,15 @@ let memoizedIncludes = {};

 module.exports = {
   include_raw: (file) => {
-    if (file in memoizedIncludes) {
-      return memoizedIncludes[file];
-    } else {
-      let content = fs.readFileSync(file, 'utf8');
-      memoizedIncludes[file] = content;
-      return content;
-    }
+    // console.log({file});
+    return "RAWR FILE";
+
+    // if (file in memoizedIncludes) {
+    //   return memoizedIncludes[file];
+    // } else {
+    //   let content = fs.readFileSync(file, 'utf8');
+    //   memoizedIncludes[file] = content;
+    //   return content;
+    // }
   },
 };

diff --git a/src/_data/eleventyComputed.js b/src/_data/eleventyComputed.js
index 66be9a4e..2523e6c3 100644
--- a/src/_data/eleventyComputed.js
+++ b/src/_data/eleventyComputed.js
@@ -238,10 +238,10 @@ module.exports = {
   },
   lead: (data) => lead(data),
   // tags: (data) => tags(data),
-  permalink: (data) =>
-    data.layout === 'draft' && process.env.NODE_ENV === 'production'
-      ? false
-      : data.permalink,
+  permalink: (data) => data.permalink,
   eleventyExcludeFromCollections: (data) =>
     data.layout === 'draft' && process.env.NODE_ENV === 'production',
 };

Curious if the permalink: false is related to a global eleventyComputed.js file style, or if you'd have the same behavior in a directory data file. I'm pretty sure I've used that pattern in front matter and data directories of returning false before without issues, but I don't usually use global eleventyComputed.js files.

nhoizey commented 3 years ago

@pdehaan thanks a lot for taking time to help me!

include_raw.js should not behave differently for production and development builds.

Setting permalink to false in the global eleventyComputed.js file works in my reduced test case.

But what I found is that even if eleventyComputed.js sets permalink to false, the template/layout tries to generate the content. And the layout tries to use page.outputPath or page.url multiple times with string based functions, but their values is false.

I will build a reduced test case for this.

nhoizey commented 3 years ago

Here's the reduced test case, in the computed-permalink-false branch of this repository: https://github.com/nhoizey/11ty-reduced-test-cases/tree/computed-permalink-false

nhoizey commented 3 years ago

I finally found where it came from, as explained in #1700 :

I had to add checks for false value of {{ page.url }} or {{ page.outputPath }} in some templates/layouts, because I had issue when using them with filters when their value is false.

For example, I had to replace {% if 'archives' in page.url %} with {% if page.url != false and 'archives' in page.url %}.

I don't know if Eleventy (with Nunjucks maybe) could show in the error logs that the issue comes from {% if 'archives' in page.url %}, for example.

timseverien commented 3 years ago

I ran into the same issue and the page.url !== false workaround worked for me.

I can’t help but wonder: if permalink is set to false, why would eleventy bother to render the page?

solution-loisir commented 3 years ago

I ran into the same issue and the page.url !== false workaround worked for me.

I can’t help but wonder: if permalink is set to false, why would eleventy bother to render the page?

I think that the permalink: false current behavior is suppose to get 'fixed' in version 1.0 coming out very soon (5 days if I read the signs correctly!)

augnustin commented 1 year ago

Same issue here :( No idea where to add some page.url !== false tests. I'm stucked.

No chance to get a clearer error message?

uncenter commented 1 year ago

This looks like a pretty old issue... can you confirm that you are on Eleventy v2.0.1 and then make an MRE? Often you'll figure out what your issue was while trying to reproduce so that'll be helpful either way.