gatsbyjs/gatsby · error
You must specify either a cache or a directory
Error message
You must specify either a cache or a directory
What it means
Thrown by fetchRemoteFile when the caller supplies neither a `cache` object (with a .directory) nor a `directory` string. The function needs a writable location to store the downloaded file, and this guard refuses to proceed before computing paths or touching the mutex/db.
Source
Thrown at packages/gatsby-core-utils/src/fetch-remote-file.ts:151
async function fetchFile({
url,
cache,
directory,
auth = {},
httpHeaders = {},
ext,
name,
cacheKey,
excludeDigest,
}: IFetchRemoteFileOptions): Promise<string> {
// global introduced in gatsby 4.0.0
const BUILD_ID = global.__GATSBY?.buildId ?? ``
const fileDirectory = (cache ? cache.directory : directory) as string
const storage = getStorage(getDatabaseDir())
if (!cache && !directory) {
throw new Error(`You must specify either a cache or a directory`)
}
const fetchFileMutex = createMutex(`gatsby-core-utils:fetch:${url}`)
await fetchFileMutex.acquire()
// Fetch the file.
try {
const digest = createContentDigest(url)
const finalDirectory = excludeDigest
? path.resolve(fileDirectory)
: path.join(fileDirectory, digest)
if (!name) {
name = getRemoteFileName(url)
}
if (!ext) {
ext = getRemoteFileExtension(url)View on GitHub (pinned to 8b06340921)
Solutions
- Pass the Gatsby cache: fetchRemoteFile({ url, cache, ... }) — cache comes from the onCreateNode/etc. helper args and exposes .directory.
- Or pass an explicit directory string if you manage storage yourself.
- If you only need the bytes transiently, supply a temp directory under os.tmpdir().
Example fix
// before
await fetchRemoteFile({ url, ext, name })
// after (forward cache from node helpers)
await fetchRemoteFile({ url, ext, name, cache }) Defensive patterns
Strategy: validation
Validate before calling
if (!cache && !directory) throw new Error('cache or directory required')
await fetchRemoteFile({ url, cache, directory }) Type guard
const hasStorage = (o: { cache?: { directory: string }; directory?: string }): boolean =>
!!o?.cache?.directory || typeof o?.directory === 'string' Prevention
- Always forward the Gatsby `cache` from helper args when calling fetchRemoteFile.
- Pass an explicit directory when managing storage yourself.
- Wrap the call in a helper that asserts storage presence.
When it happens
Trigger: Calling fetchRemoteFile({ url, ... }) with both `cache` and `directory` omitted; passing cache as undefined and directory as undefined/null; integrating the helper directly (outside gatsby-source-*) and forgetting the storage option.
Common situations: Custom source plugins or scripts invoking fetchRemoteFile standalone without forwarding the Gatsby cache; refactoring a source plugin and dropping the cache arg; migrating from an older signature that defaulted directory.
Related errors
- Neither "cache" or "getCache" was passed. getCache must be f
- Neither "cache" or "getCache" was passed. getCache must be f
- Neither "cache" or "getCache" was passed. getCache must be f
- The prop `fluid` or `fixed` is marked as required in `${comp
- ${JSON.stringify(result)}
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/ea93fa8a9d77759a.
Report an issue: GitHub.