gatsbyjs/gatsby · error · Error

Neither "cache" or "getCache" was passed. getCache must be…

Error message

Neither "cache" or "getCache" was passed. getCache must be function that return Gatsby cache, "cache" must be the Gatsby cache, was ${typeof cache}

What it means

createRemoteFileNode needs a cache to store download metadata, dedupe URLs (processingCache is persisted across builds), and track content digests. After trying `getCache('gatsby-source-filesystem')`, if `cache` is still not an object this error fires. The message names both accepted inputs so callers know the two ways to satisfy the requirement.

Solutions

  1. Forward cache from helpers: exports.sourceNodes = async ({ cache, actions, createNodeId }) => { await createRemoteFileNode({ url, cache, createNode: actions.createNode, createNodeId }) }.
  2. If cache is not directly available, pass getCache so the plugin resolves its own namespaced cache.
  3. Confirm the cache object is the Gatsby cache (has get/set/del) and not an unrelated object.
  4. Avoid calling createRemoteFileNode outside of a lifecycle that provides cache.

Example fix

// before
await createRemoteFileNode({
  url,
  createNode,
  createNodeId,
})

// after
await createRemoteFileNode({
  url,
  cache,
  createNode,
  createNodeId,
})
Defensive patterns

Strategy: validation

Validate before calling

if (!(typeof cache === 'object' && cache) && typeof getCache !== 'function') {
  throw new Error('createRemoteFileNode needs cache or getCache from helpers')
}

Type guard

const isCache = (v) => v && typeof v === 'object' && typeof v.get === 'function'

Try / catch

try { await createRemoteFileNode(opts) } catch (e) { if (/Neither "cache" or "getCache"/.test(e.message)) { reporter.panic('Cache not forwarded to createRemoteFileNode') } throw e }

Prevention

When it happens

Trigger: Calling createRemoteFileNode without cache or getCache; passing cache: undefined after a refactor; passing a plain object that is not the Gatsby cache instance; using the API inside onPreInit or another lifecycle that lacks cache.

Common situations: Migrating to a newer gatsby-source-filesystem where cache became required; copying example code that omitted cache; building a transformer plugin that calls createRemoteFileNode without forwarding helpers; CI environments where the cache dir is unwritable causing cache resolution to return non-object.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/17fa0d5694a68a0b. Report an issue: GitHub.

Appendix: source

Thrown at packages/gatsby-source-filesystem/src/create-remote-file-node.js:127

  name = null,
}) {
  // validation of the input
  // without this it's notoriously easy to pass in the wrong `createNodeId`
  // see gatsbyjs/gatsby#6643
  if (typeof createNodeId !== `function`) {
    throw new Error(
      `createNodeId must be a function, was ${typeof createNodeId}`
    )
  }
  if (typeof createNode !== `function`) {
    throw new Error(`createNode must be a function, was ${typeof createNode}`)
  }
  if (typeof getCache === `function`) {
    // use cache of this plugin and not cache of function caller
    cache = getCache(`gatsby-source-filesystem`)
  }
  if (typeof cache !== `object`) {
    throw new Error(
      `Neither "cache" or "getCache" was passed. getCache must be function that return Gatsby cache, "cache" must be the Gatsby cache, was ${typeof cache}`
    )
  }

  // Check if we already requested node for this remote file
  // and return stored promise if we did.
  if (processingCache[url]) {
    return processingCache[url]
  }

  if (!url || isWebUri(url) === undefined) {
    throw new Error(
      `url passed to createRemoteFileNode is either missing or not a proper web uri: ${url}`
    )
  }

  const fileDownloadPromise = processRemoteNode({
    url,

View on GitHub (pinned to 8b06340921)