{"record":{"id":"7ca9e48a59107886","repo":"gatsbyjs/gatsby","slug":"createnodeid-must-be-a-function-was-typeof-crea-7ca9e4","errorCode":null,"errorMessage":"createNodeId must be a function, was ${typeof createNodeId}","messagePattern":"createNodeId 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":115,"sourceCode":" * @return {Promise<Object>}                  Returns the created node\n */\nmodule.exports = function createRemoteFileNode({\n  url,\n  cache,\n  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.","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-source-filesystem/src/create-remote-file-node.js#L97-L133","documentation":"createRemoteFileNode validates that `createNodeId` is a function before doing anything else. This guard exists because it is famously easy to pass the wrong createNodeId shape (see gatsbyjs/gatsby#6643). createNodeId turns a stable string into the Gatsby node id used to dedupe and reference the downloaded file. Anything that is not a function — undefined, a string, an object — fails fast with its runtime type.","triggerScenarios":"Calling createRemoteFileNode({ url }) without createNodeId; passing createNodeId: undefined; passing the createNodeId result string instead of the function; calling from a non-Gatsby context where helpers were not forwarded.","commonSituations":"Using createRemoteFileNode insidegatsby-node.js sourceNodes but destructuring helpers incorrectly; copy-pasting example that omits createNodeId; upgrading gatsby-source-filesystem where the parameter ordering/requirements tightened; calling from a standalone script with no Gatsby runtime.","solutions":["Pass createNodeId from Gatsby helpers: in exports.sourceNodes = ({ actions, createNodeId, cache }) => { ... createRemoteFileNode({ url, createNodeId, createNode, cache }) }.","Confirm createNodeId is the function reference, not a result of calling it (createNodeId vs createNodeId('foo')).","If invoking outside sourceNodes, obtain createNodeId from the Gatsby node API helpers and forward it explicitly.","Add a typeof createNodeId === 'function' assert at the entry of your own wrapper to fail with a clearer message."],"exampleFix":"// before\nawait createRemoteFileNode({ url, cache, createNode })\n\n// after\nawait createRemoteFileNode({\n  url,\n  cache,\n  createNode,\n  createNodeId,\n})","handlingStrategy":"type-guard","validationCode":"if (typeof createNodeId !== 'function') {\n  throw new TypeError('createNodeId missing; forward it from Gatsby helpers')\n}","typeGuard":"const isCreateNodeId = (v) => typeof v === 'function'","tryCatchPattern":"try { await createRemoteFileNode(opts) } catch (e) { if (/createNodeId must be a function/.test(e.message)) { reporter.panic('createNodeId not forwarded from helpers') } throw e }","preventionTips":["Destructure createNodeId directly from the sourceNodes helpers argument","Forward all helpers as a group to avoid dropping one","Add a unit test that asserts the call succeeds with real helpers"],"tags":["gatsby","validation","config","createnodeid"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}