{"record":{"id":"34b497c2de25babb","repo":"gatsbyjs/gatsby","slug":"createnode-must-be-a-function-was-typeof-create-34b497","errorCode":null,"errorMessage":"createNode must be a function, was ${typeof createNode}","messagePattern":"createNode must be a function, was (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/gatsby-source-filesystem/src/create-remote-file-node.js","lineNumber":120,"sourceCode":"  createNode,\n  getCache,\n  parentNodeId = null,\n  auth = {},\n  httpHeaders = {},\n  createNodeId,\n  ext = null,\n  name = null,\n}) {\n  // validation of the input\n  // without this it's notoriously easy to pass in the wrong `createNodeId`\n  // see gatsbyjs/gatsby#6643\n  if (typeof createNodeId !== `function`) {\n    throw new Error(\n      `createNodeId must be a function, was ${typeof createNodeId}`\n    )\n  }\n  if (typeof createNode !== `function`) {\n    throw new Error(`createNode must be a function, was ${typeof createNode}`)\n  }\n  if (typeof getCache === `function`) {\n    // use cache of this plugin and not cache of function caller\n    cache = getCache(`gatsby-source-filesystem`)\n  }\n  if (typeof cache !== `object`) {\n    throw new Error(\n      `Neither \"cache\" or \"getCache\" was passed. getCache must be function that return Gatsby cache, \"cache\" must be the Gatsby cache, was ${typeof cache}`\n    )\n  }\n\n  // Check if we already requested node for this remote file\n  // and return stored promise if we did.\n  if (processingCache[url]) {\n    return processingCache[url]\n  }\n\n  if (!url || isWebUri(url) === undefined) {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-source-filesystem/src/create-remote-file-node.js#L102-L138","documentation":"createRemoteFileNode requires `createNode` to be a function because it must register the downloaded file as a Gatsby node. This check fires after the createNodeId check and rejects any non-function (undefined, null, object). Without a working createNode, the file would be downloaded but never appear in the Gatsby data layer.","triggerScenarios":"Omitting createNode from the options; passing actions instead of actions.createNode; passing createNode: undefined from a broken destructuring; calling createRemoteFileNode from a context where actions were not captured.","commonSituations":"Destructuring only `createNodeId` and `cache` from helpers but forgetting `actions.createNode`; refactoring that moves createNode into a closure that is out of scope; examples in documentation that abbreviate the call.","solutions":["Pass the bound action: const { createNode } = actions; then createRemoteFileNode({ url, createNode, createNodeId, cache }).","Confirm the sourceNodes hook signature destructures actions: exports.sourceNodes = async ({ actions, createNodeId, cache }) => { ... }.","Forward createNode through any wrapper function explicitly rather than relying on closure capture.","Verify typeof createNode === 'function' at the boundary of your wrapper."],"exampleFix":"// before\nconst { createNodeId, cache } = helpers\nawait createRemoteFileNode({ url, createNodeId, cache })\n\n// after\nconst { createNodeId, cache, actions: { createNode } } = helpers\nawait createRemoteFileNode({ url, createNodeId, cache, createNode })","handlingStrategy":"type-guard","validationCode":"if (typeof createNode !== 'function') {\n  throw new TypeError('createNode missing; destructure it from actions')\n}","typeGuard":"const isCreateNode = (v) => typeof v === 'function'","tryCatchPattern":"try { await createRemoteFileNode(opts) } catch (e) { if (/createNode must be a function/.test(e.message)) { reporter.panic('actions.createNode not forwarded') } throw e }","preventionTips":["Pull createNode from actions: const { createNode } = actions","Pass the full helpers + actions objects through wrapper functions","Lint against using createRemoteFileNode without a createNode binding in scope"],"tags":["gatsby","validation","config","createnode"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}