Gatsby: Hot reloading error: "path" argument must be of type string

Created on 14 Oct 2019  路  17Comments  路  Source: gatsbyjs/gatsby

Hot reloading in gatsby develop gives this error in my project. Hot reloading sometimes works despite the error (as in, I see the error in the console window where I ran gatsby develop, but the website in browser appears to hot reload and work just fine). This error appeared after I updated some (mainly Gatsby) npm dependencies. Stack trace is giving me no ideas on how to debug this. Is it a Gatsby bug?

Note that this error only comes up on hot reload. So I can run gatsby develop just fine as long as I don't make any changes to any files. I can also build just fine.

[ { TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
      at assertPath (path.js:39:11)
      at Object.resolve (path.js:1085:7)
      at findLinkedFileNode (/.../node_modules/gatsby/dist/schema/resolvers.js:208:47)
      at resolveValue (/.../node_modules/gatsby/dist/schema/resolvers.js:223:108)
      at /.../node_modules/gatsby/dist/schema/resolvers.js:220:10
      at process._tickCallback (internal/process/next_tick.js:68:7)
    message:
     'The "path" argument must be of type string. Received type undefined',
    locations: [ [Object] ],
    path:
     [ 'allMarkdownRemark', 'edges', 0, 'node', 'frontmatter', 'cover' ] } ]

confirmed bug

Most helpful comment

A fix by @sdobz totally works as a dirty temporary solution. The error stops breaking gatsby, and you just need to hit refresh to see your changes (not ideal, but whatever, it's better then restarting gatsby every time I save a file)

This is still a pressing issue though, rendering gatsby develop unusable for, well, development. It would be really cool if some one from the core team addressed it soon 馃槑

All 17 comments

Are you able to share your project so we could reproduce and debug?

Thanks for offering to help! The project is here: https://github.com/baobabKoodaa/blog

Steps to reproduce:

  1. git clone [email protected]:baobabKoodaa/blog.git
  2. npm install
  3. gatsby develop
  4. modify a blog post inside content/mock_posts. When you save, the content should hot reload in browser while simultaneously giving the error in the console window where you ran gatsby develop.

Also, this commit (npm update) caused the error to appear: https://github.com/baobabKoodaa/blog/commit/2cfb359cd322a58eb809a667dc6dc4e1dad8e2ba

The error will disappear if you revert package.json and package-lock.json to their state before that commit.

I'm interested in looking into this. @pieh , Mind if I poke around and see if I can resolve the issue?

So what I found is that the markdown front matter is getting confused as a ContextualNodeModel. So when you run Path.resolve(args), it is getting the front matter object, which doesn't have the 'dir' attribute. I'm going to throw up a PR for the fix.

I see this error too and the attached PR fixes the error for me. Haven't seen any unwanted side effects so far.

I was just reviewing this, and while this fixes the error, it doesn't fix the root issue.

This happens when you query File fields inside gatsby-node -> createPages.

Using @baobabKoodaa repro, and logging out query result in createPages I do get:

{
    title: 'Two things are infinite the universe and human stupidity',
    tags: [ 'sayings', 'wisdom' ],
    cover: [Object: null prototype] { children: [Array] } }

on initial createPages call, and after editing that page, we'll receive:

{
    title: 'Two things are infinite the universe and human stupidity',
    tags: [ 'sayings', 'wisdom' ],
    cover: null }

which showcases where this problem is. The PR just silences the error

Ok, so few details here:

This part in fileByPath: https://github.com/gatsbyjs/gatsby/blob/ea00e523ce5c32040c931bfe4bef081b11b13f68/packages/gatsby/src/schema/resolvers.js#L216-L219 is supposed to find File node that is ancestor (parent, parent of parent, and so-on) of node that contains source object (source might be node itself as well).

The general structure looks like this:

// File node (markdown)
{
  id: "some-markdown-file-node-id",
  dir: "/some/directory",
  absolutePath: "/some/directory/index.md",
  internal: {
    type: "File",
  }
}

// File node (image)
{
  id: "some-image-file-node-id",
  dir: "/some/directory",
  absolutePath: "/some/directory/image.png",
  internal: {
    type: "File",
  }
}

// Remark/mdx node
{
  id: "some-other-id",
  parent: "some-markdown-file-node-id", // <- important - this is child node of File node
  frontmatter: {
    image: "./image.png"
  },
  internal: {
    type: "MarkdownRemark"
  }
}

Now - in the fileByPath resolver, source will be frontmatter object - the object itself, doesn't really have information what node it belongs to. We do use "node tracking" for this, which maps objects to nodes that "own" them (see https://www.gatsbyjs.org/docs/node-tracking/ for some information about this, the links are most likely very out of date, but the explanation is still correct).

It does seem that node tracking is problematic here. Now it generally still works (because page queries, static queries and initial createPages query works), but it breaks for subsequent query running and this is what needs to be figured out

Ok, update:
Comment above is correct - just more details on why this happens:
In our node tracking code, we check if node is being tracked by using "tracked nodes" list that contain node IDs: https://github.com/gatsbyjs/gatsby/blob/95e908e3605eb2a0a240801f6c8ac5677ba9d6d7/packages/gatsby/src/schema/node-model.js#L336-L339

So when node is being updated (preserving its ID), we don't track new node.

This problem is not visible in page/static queries because we reset the entire "Node model" instance (which removes/resets list of tracked nodes and bunch of other things related to Materialization) in https://github.com/gatsbyjs/gatsby/blob/95e908e3605eb2a0a240801f6c8ac5677ba9d6d7/packages/gatsby/src/query/index.js#L349-L362 (graphqlRunner is object that have instance of "Node model, so resetting runner also resets used "Node model")

We could do the same for graphql function being used in gatsby-node APIs (including createPages) - https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/bootstrap/graphql-runner.js (I just did dirty test and it seems to fix the issue).

But this raises question - we have multiple unrelated "Node model" instances which potentially cause duplicate work that those "Node model" instances do - maybe there should be single "Node model" instance that will reset itself when needed so graphql runners don't need to care about this detail (and also this could avoid potential duplicate work) - this is tricky issue and I think we should first fix it by resetting graphql runner used in gatsby-node APIs (similar to development query runner queue)

/cc @freiksenet

I'm seeing this behaviour as well and am here to test if/when needed. :)

I have this behaviour and it's becoming a bit frustrating. Mine it's related to my "hero" image inside markdown files (not mdx):

By the way, just few days ago the error was more detailed, since it was related to "hero".
It said something like: The "hero" argument must be of type object. Received type undefined

This is the error now:

 ERROR #11321  PLUGIN

"gatsby-node.js" threw an error while running the createPages lifecycle:

The "path" argument must be of type string. Received type undefined

GraphQL request:9:15
 8 |   title
 9 |   hero {
   |               ^
10 |           childImageSharp{

failed createPages - 4.121s

this is my graphql query under gatsby-node.js file

{
allMarkdownRemark(sort: {fields: frontmatter___date, order: ASC}) {
    edges {
      node {
        frontmatter {
          imghero
          slug
          title
          hero {
            childImageSharp {
              fluid(maxWidth: 700, quality: 85) {
                src
              }
            }
          }
        }
      }
    }
  }
}

Also I'm here to test if needed

Just wanted to note that this issue still exists in gatsby 2.18.5.

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

I have the same issue I tried every possible solution with no luck, any updates from you guys?

Me too, I tried also to modified my gatsby-node.js removing the Promise() and cleaning up things, it works but with inconsistency errors.

  Binaries:
    Node: 11.12.0 - /usr/bin/node
    Yarn: 1.21.0 - /usr/bin/yarn
    npm: 6.9.0 - /usr/bin/npm

    gatsby: ^2.18.14 => 2.18.17 
    gatsby-plugin-sharp: ^2.3.9 => 2.3.10 
    gatsby-remark-images: ^3.1.38 => 3.1.39 
    gatsby-remark-responsive-iframe: ^2.2.30 => 2.2.30 
    gatsby-source-filesystem: ^2.1.42 => 2.1.43 
    gatsby-transformer-remark: ^2.6.44 => 2.6.45 
    gatsby-transformer-sharp: ^2.3.9 => 2.3.9 

  npmGlobalPackages:
    gatsby-cli: 2.8.22

my gatsby-node.js went from this:

const path = require('path');

exports.createPages = ({ graphql, actions}) => {
  const {createPage} = actions;
  return new Promise ((resolve, reject) => {
    graphql(`
    {
    allMarkdownRemark(sort: {fields: frontmatter___date, order: ASC}){
      edges {
        node {
          frontmatter {
              slug
              title
              imghero
              hero {
                childImageSharp{
                  fluid(maxWidth: 700, quality: 85) {
                    src
                  }
                }
              }
            }
          }
        }
      }
    }
    `).then(results => {
      if (results.errors) {
        reject(results.errors)
      }

    // Posts
    const posts = results.data.allMarkdownRemark.edges
      posts.forEach(({node}, index) =>{
          createPage({
              path: node.frontmatter.slug,
              component: path.resolve('./src/templates/postLayout.js'),
              context: {
                  slug: node.frontmatter.slug,
                  prev: index === 0 ? null : posts[index -1].node,
                  next: index === (posts.length - 1) ? null : posts[index + 1].node
              }
          });
      })

    resolve();
    })
  })
}

to this one (as you can notice I remove the New Promise since I read that gatsby-node runs a promise by default. This works but only if I removed the error condition after results. With this gatsby-node.js the bug will not appear on the terminal but it will still be present, and sometimes it will throw an error and even shut down the developer session):

const path = require('path');

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;
  return graphql(`
    {
      allMarkdownRemark(sort: {fields: frontmatter___date, order: ASC}){
        edges {
          node {
            frontmatter {
              slug
              title
              imghero
              hero {
                childImageSharp{
                  fluid(maxWidth: 700, quality: 85) {
                    src
                  }
                }
              }
            }
          }
        }
      }
    }
    `).then(result => {

    // POSTS
    const posts = result.data.allMarkdownRemark.edges
    const blogPostTemplate = path.resolve('./src/templates/postLayout.js')
    posts.forEach(({ node }, index) => {
      const path = `${node.frontmatter.slug}`
      createPage({
        path,
        component: blogPostTemplate,
        context: {
          slug: path,
          prev: index === 0 ? null : posts[index - 1].node,
          next: index === (posts.length - 1) ? null : posts[index + 1].node
        }
      });
    })
  })
}

@pieh could you share the dirty fix? I'm wallowing around in code I don't understand looking for a place to do additional node tracking when a node is hot reloaded. Is this the right track? What files should I look in to get a handle on the hot reload lifecycle?

A fix by @sdobz totally works as a dirty temporary solution. The error stops breaking gatsby, and you just need to hit refresh to see your changes (not ideal, but whatever, it's better then restarting gatsby every time I save a file)

This is still a pressing issue though, rendering gatsby develop unusable for, well, development. It would be really cool if some one from the core team addressed it soon 馃槑

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rossPatton picture rossPatton  路  3Comments

dustinhorton picture dustinhorton  路  3Comments

3CordGuy picture 3CordGuy  路  3Comments

benstr picture benstr  路  3Comments

dustinhorton picture dustinhorton  路  3Comments