Gatsby: [v2] gatsbyNode[api] is not a function

Created on 5 Jul 2018  Β·  18Comments  Β·  Source: gatsbyjs/gatsby

Description

Getting a TypeError: gatsbyNode[api] is not a function error when trying to start up after migration to Gatsby v2.

To get started, we ran through the documentation and whatever debugging we could figure out via the issues: https://next.gatsbyjs.org/docs/migrating-from-v1-to-v2/

Please let me know if I missed anything below. Thanks in advance

Steps to reproduce

gatsby develop

Expected result

Site should compile

Actual result

TypeError: gatsbyNode[api] is not a function
- api-runner-node.js:104 runAPI
  [website]/[gatsby]/dist/utils/api-runner-node.js:104:37
- api-runner-node.js:173 mapSeries
  [website]/[gatsby]/dist/utils/api-runner-node.js:173:25
- map.js:27
  [website]/[async]/internal/map.js:27:9
- eachOfLimit.js:66 replenish
  [website]/[async]/internal/eachOfLimit.js:66:17
- eachOfLimit.js:50 iterateeCallback
  [website]/[async]/internal/eachOfLimit.js:50:17
- onlyOnce.js:12
  [website]/[async]/internal/onlyOnce.js:12:16
- map.js:29
  [website]/[async]/internal/map.js:29:13
- util.js:16 tryCatcher
  [website]/[bluebird]/js/release/util.js:16:23
- nodeify.js:23 Promise.successAdapter
  [website]/[bluebird]/js/release/nodeify.js:23:30
- promise.js:566 Promise._settlePromise
  [website]/[bluebird]/js/release/promise.js:566:21
- promise.js:606 Promise._settlePromiseCtx
  [website]/[bluebird]/js/release/promise.js:606:10
- async.js:138 Async._drainQueue
  [website]/[bluebird]/js/release/async.js:138:12
- async.js:143 Async._drainQueues
  [website]/[bluebird]/js/release/async.js:143:10
- async.js:17 Immediate.Async.drainQueues [as _onImmediate]
  [website]/[bluebird]/js/release/async.js:17:14
gatsby develop exited with code 1

Environment

Can't seem to get gatsby info to work πŸ€”here's the gatsby-named items from the yarn.lock

gatsby-cli@^2.0.0-beta.3, gatsby-cli@next:
  version "2.0.0-beta.3"
gatsby-link@^2.0.0-beta.4:
  version "2.0.0-beta.4"
gatsby-plugin-ngrok-tunneling@next:
  version "1.1.3"
gatsby-plugin-page-creator@^2.0.0-beta.2:
  version "2.0.0-beta.2"
gatsby-plugin-react-helmet@next:
  version "3.0.0-beta.3"
gatsby-plugin-resolve-src@next:
  version "1.1.3"
gatsby-plugin-sass@next:
  version "2.0.0-beta.3"
gatsby-plugin-sitemap@next:
  version "2.0.0-beta.2"
gatsby-react-router-scroll@^2.0.0-beta.2:
  version "2.0.0-beta.2"
gatsby-source-filesystem@next:
  version "2.0.1-beta.3"
gatsby@next:
  version "2.0.0-beta.17"

File contents (if changed)

gatsby-config.js:

module.exports = {
  siteMetadata: {
    siteUrl: 'https://www.website.com',
  },
  plugins: [
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-sass',
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/pages`,
        name: 'pages',
      },
    },
    {
      resolve: `gatsby-plugin-sitemap`,
      options: {
        exclude: [
          '/thank-you',
          '/test',
          '/blog*',
          '/blog/*',
        ],
      },
    },
    'gatsby-plugin-resolve-src'
  ],
};

package.json:

{
  ...author info...
  "dependencies": {
    "@fortawesome/fontawesome": "^1.1.8",
    "@fortawesome/fontawesome-free-solid": "^5.0.13",
    "@fortawesome/fontawesome-svg-core": "^1.2.0",
    "@fortawesome/react-fontawesome": "^0.1.0",
    "async-request": "^1.2.0",
    "catalog": "^3.5.4",
    "chokidar-cli": "^1.2.0",
    "concurrently": "^3.6.0",
    "crypto": "^1.0.1",
    "g": "^2.0.1",
    "gatsby": "next",
    "gatsby-cli": "next",
    "gatsby-plugin-ngrok-tunneling": "next",
    "gatsby-plugin-react-helmet": "next",
    "gatsby-plugin-resolve-src": "next",
    "gatsby-plugin-sass": "next",
    "gatsby-plugin-sitemap": "next",
    "gatsby-source-filesystem": "next",
    "history": "^4.7.2",
    "html-entities": "^1.2.1",
    "ngrok": "^3.0.1",
    "node-sass-chokidar": "^1.1.0",
    "parameterize": "^0.1.0",
    "promise-polyfill": "8.0.0",
    "react": "^16.2.0",
    "react-anchor-link-smooth-scroll": "^1.0.10",
    "react-countup": "^3.0.3",
    "react-dom": "^16.2.0",
    "react-helmet": "^5.2.0",
    "react-redux": "^5.0.7",
    "react-router-hash-link": "^1.2.0",
    "react-tabs": "^2.2.2",
    "redux": "^4.0.0",
    "whatwg-fetch": "^2.0.4"
  },
  "keywords": [
    "gatsby"
  ],
  "license": "MIT",
  "main": "n/a",
  "scripts": {
    "build": "gatsby build",
    "style": "yarn catalog-start",
    "develop": "rm -rf .cache && concurrently --names \" WATCH, GATSBY\" -c \"bgBlue.bold\" --kill-others \"yarn watch-css\" \"gatsby develop\"",
    "developstyle": "rm -rf .cache && concurrently --names \" WATCH ,CATALOG, GATSBY\" -c \"bgBlue.bold\" --kill-others \"yarn watch-css\" \"yarn style\" \"gatsby develop\"",
    "format": "prettier --trailing-comma es5 --single-quote --write \"**/*.js\"",
    "lint": "eslint \"**/*.js\" && echo \"πŸ‘  Passed linting\n\"",
    "precommit": "yarn test && yarn lint && echo \"😎  Passed precommit steps. Commiting now.\n\"",
    "test": "echo \"πŸ‘  Passed tests (no tests defined yet)\n\"",
    "catalog-start": "catalog start",
    "catalog-build": "catalog build",
    "build-css": "node-sass-chokidar ./src/assets/stylesheets/application.scss -o ./catalog/css",
    "tunnel": "ngrok http 8000",
    "watch-css": "yarn build-css && chokidar ./src/assets/stylesheets/ -c \"yarn build-css\""
  },
  "devDependencies": {
    "css-loader": "^0.28.10",
    "eslint": "^5.0.1",
    "eslint-plugin-react": "^7.10.0",
    "husky": "^0.14.3",
    "node-sass": "^4.9.1",
    "prettier": "^1.13.7",
    "sass-loader": "^7.0.3",
    "style-loader": "^0.21.0"
  }
}

gatsby-node.js:

exports.onCreateWebpackConfig = require('./gatsby-node/webpack-config');
exports.sourceNodes = require('./gatsby-node/source-nodes');
exports.createPages = require('./gatsby-node/create-pages');
// ./gatsby-node/webpack-config
exports.onCreateWebpackConfig = require('./gatsby-node/webpack-config');
exports.sourceNodes = require('./gatsby-node/source-nodes');
exports.createPages = require('./gatsby-node/create-pages');



md5-bc8b9b00b159a2a64673177ad157a2ea



// ./gatsby-node/source-nodes/index.js
const getPages = require('./types/page');
const getPosts = require('./types/post');
const getEmployees = require('./types/employee');

// Create Nodes from API request
// Nodes are where data is kept in Graphql

module.exports = async ({ boundActionCreators }) => {
  const { createNode } = boundActionCreators;

  // Posts & pages requests run concurrently as not to
  // Bog down the event loop
  await Promise.all([
    getPosts(createNode),
    getPages(createNode),
    getEmployees(createNode),
  ]);

  return;
};



md5-bc8b9b00b159a2a64673177ad157a2ea



// ./gatsby-node/create-pages
const path = require('path');

// –––––– createPages ––––––

module.exports = ({ boundActionCreators, graphql }) => {
  const { createPage } = boundActionCreators;

  return new Promise(resolve => {
    // query JSON Pages

    const pageQuery = graphql(`
      {
        allJsonPage {
          edges {
            node {
              name
              slug
              id
              template
            }
          }
        }
      }
    `);

    pageQuery.then(result => {
      const nodes = result.data.allJsonPage.edges.map(edge => edge.node);

      nodes.forEach(node => {
        if (node.template === 'none' || !node.template) return;

        const pageConfig = {
          path: node.slug,
          component: path.resolve(`src/templates/${node.template}.js`),
          context: {
            name: node.name,
            slug: node.slug,
          },
        };

        createPage(pageConfig);
      });
    });

    // Query JSON posts

    const postQuery = graphql(`
      {
        allJsonPost {
          edges {
            node {
              name
              slug
              id
            }
          }
        }
      }
    `);

    postQuery.then(result => {
      const nodes = result.data.allJsonPost.edges.map(edge => edge.node);

      nodes.forEach(node => {
        const postConfig = {
          path: node.slug,
          component: path.resolve('src/templates/post.js'),
          context: {
            name: node.name,
            slug: node.slug,
          },
        };

        createPage(postConfig);
      });
    });

    // if all previous JS has run, Promise can be resolved

    resolve();
  }).catch(error => console.log(error));
};



md5-d9f854b8e7c03852ae9b9ac947e0107d



import React from 'react';
import { Router } from 'react-router-dom';
import { Provider } from 'react-redux';

import createStore from './src/state/createStore';

exports.replaceRouterComponent = ({ history }) => {
  const store = createStore();

  const ConnectedRouterWrapper = ({ children }) => (
    <Provider store={store}>
      <Router history={history}>{children}</Router>
    </Provider>
  );

  return ConnectedRouterWrapper;
};



md5-0abd66f887039426bece8e9173a539ce



import React from 'react';
import { Provider } from 'react-redux';
import { renderToString } from 'react-dom/server';

import createStore from './src/state/createStore';

exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
  const store = createStore();

  const ConnectedBody = () => (
    <Provider store={store}>{bodyComponent}</Provider>
  );

  replaceBodyHTMLString(renderToString(<ConnectedBody />));
};
question or discussion

Most helpful comment

@gregoryforel the issue is that gatsby-node.js (CommonJS) is requiring (via ts-node) a Typescript file, which is an and of itself, fine.

However, the issue is that you're presuming the "default" (i.e. module.exports) with this line in gatsby-node.js

exports.createPages = require('./createPages')

when createPages.ts actually contains

export const createPages = () => {};

so you can fix that in a few ways. Easiest is just changing the require statement in gatsby-node.js

exports.createPages = require('./createPages').createPages

All 18 comments

I'm not sure what's causing that... as a debugging step I'd try moving the code from your various ./gatsby-node/ requires back into the main gatsby-node.js. If that works, then move things out bit by bit until you can reproduce the error.

good call. it looks like the webpack config import was the offender, perhaps there's an issue with the export. will just carry on with that particular one in the gatsby-node file. thanks for the help

@colbyfayock Have you ever found out? Facing the same error message. Thanks!

@gregoryforel could you share a repo or reproduction of the issue? It's likely that you're exporting an API (i.e. in a file) that isn't an actual Gatsby API!

@gregoryforel it had to do with how I was running the exports relating to the custom webpack config, but i didn't ever figure out the exact issue as we didn't even need the custom config anymore. if you're able to provide some code to look at like DSchau mentioned, we might be able to help debug

@colbyfayock @DSchau I'm really new to Gatsby and GraphCMS. So far, just trying to setup a starterkit to be able to work in Typescript. I'm almost there, it was working before I tried to what clarkdave described in this thread, very last post: https://github.com/gatsbyjs/gatsby/issues/1457

@gregoryforel so we're in agreement that the repo (as authored) works just fine, right? I wasn't able to reproduce any errors!

It seems like you run into errors when you start requiring ts-node?

@DSchau Indeed. That's what I get:

yarn run v1.7.0
$ gatsby develop
success open and validate gatsby-config β€” 0.006 s
success load plugins β€” 0.173 s
success onPreInit β€” 0.323 s
success delete html and css files from previous builds β€” 0.012 s
success initialize cache β€” 0.021 s
success copy gatsby files β€” 0.076 s
success onPreBootstrap β€” 0.012 s
success source and transform nodes β€” 0.429 s
success building schema β€” 0.115 s
error gatsby-node.js returned an error


  TypeError: gatsbyNode[api] is not a function

  - api-runner-node.js:136 runAPI
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:136:22

  - api-runner-node.js:242 runAPI
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:242:9

  - util.js:16 tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - reduce.js:155 Object.gotValue
    [gatsby-source-graphql]/[bluebird]/js/release/reduce.js:155:18

  - reduce.js:144 Object.gotAccum
    [gatsby-source-graphql]/[bluebird]/js/release/reduce.js:144:25

  - util.js:16 Object.tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:17:14


error Cannot read property 'filter' of undefined


  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:266 filter
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:266:42

  - util.js:16 tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:17:14


error UNHANDLED REJECTION


  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:266 filter
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:266:42

  - util.js:16 tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:17:14


error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

@gregoryforel would you mind "breaking it" in a branch or something of the repo?

What do you mean exactly?

@gregoryforel it's hard for me to reproduce exactly what you have (that's broken) if I can't see _how_ it's broken! The repo in its current state works just fine!

@DSchau I'm so stupid... I forgot to commit my changes, I pushed the working repo. Sorry for that. Check the bugfix branch please, just uploaded it.

@gregoryforel definitely not! Happens to all of us! Checking it out now.

@gregoryforel the issue is that gatsby-node.js (CommonJS) is requiring (via ts-node) a Typescript file, which is an and of itself, fine.

However, the issue is that you're presuming the "default" (i.e. module.exports) with this line in gatsby-node.js

exports.createPages = require('./createPages')

when createPages.ts actually contains

export const createPages = () => {};

so you can fix that in a few ways. Easiest is just changing the require statement in gatsby-node.js

exports.createPages = require('./createPages').createPages

@DSchau Thank you so much, I would not have caught that. I'm peeling the onion, now seeing other errors, but I should manage. Cheers

@gregoryforel yup yup, I saw a few too :) One of them is the result of the graphql function call is an object containing a data property which contains the result of the GraphQL query. So you just need one more data subproperty, and it should be mostly good after that!

And you're very welcome. Thanks for using Gatsby πŸ’œ

@DSchau I should hire you ;)
Just solved this error too. I should not have tried to do everything at the same time: new to Gatsby, GraphQL, GraphCMS... If the user support keeps being like this, you guys have a great future

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jimfilippou picture jimfilippou  Β·  3Comments

ghost picture ghost  Β·  3Comments

totsteps picture totsteps  Β·  3Comments

benstr picture benstr  Β·  3Comments

mikestopcontinues picture mikestopcontinues  Β·  3Comments