gatsbyjs/gatsby · critical
Unable to copy site files to .cache
Error message
Unable to copy site files to .cache
What it means
During initialization Gatsby copies site files (source plugins, config) into the .cache directory and sets up the LMDB cache and fragments directory. If any of these filesystem operations fail (permission denied, disk full, path too long, antivirus lock), it panics with the underlying error attached.
Source
Thrown at packages/gatsby/src/services/initialize.ts:501
})
activity.start()
const srcDir = `${__dirname}/../../cache-dir`
const siteDir = cacheDirectory
try {
await fs.copy(srcDir, siteDir, {
overwrite: true,
})
await fs.ensureDir(`${cacheDirectory}/${lmdbCacheDirectoryName}`)
// Ensure .cache/fragments exists and is empty. We want fragments to be
// added on every run in response to data as fragments can only be added if
// the data used to create the schema they're dependent on is available.
await fs.emptyDir(`${cacheDirectory}/fragments`)
} catch (err) {
reporter.panic(`Unable to copy site files to .cache`, err)
}
// Find plugins which implement gatsby-browser and gatsby-ssr and write
// out api-runners for them.
const hasAPIFile = (env, plugin): string | undefined => {
// The plugin loader has disabled SSR APIs for this plugin. Usually due to
// multiple implementations of an API that can only be implemented once
if (env === `ssr` && plugin.skipSSR === true) return undefined
const envAPIs = plugin[`${env}APIs`]
// Always include gatsby-browser.js files if they exist as they're
// a handy place to include global styles and other global imports.
try {
if (env === `browser`) {
const modulePath = path.join(plugin.resolve, `gatsby-${env}`)
return slash(resolveModule(modulePath) as string)
}View on GitHub (pinned to 8b06340921)
Solutions
- Run `gatsby clean` (or manually delete .cache) to remove any corrupt or locked cache state.
- Check filesystem permissions on the project directory -- ensure the Node process has read/write access.
- Free disk space if the volume is full.
- On Windows, temporarily disable antivirus scanning of the project folder or add an exclusion for .cache.
- Inspect the attached `err` object for the specific filesystem error code (EACCES, ENOSPC, EPERM, etc.).
Defensive patterns
Strategy: try-catch
Validate before calling
// Check write permissions and disk space before building
const fs = require('fs-extra')
const os = require('os')
async function preBuildCheck(cacheDir) {
try {
await fs.ensureDir(cacheDir)
await fs.writeFile(cacheDir + '/.write-test', 'ok')
await fs.remove(cacheDir + '/.write-test')
} catch {
throw new Error('Cache directory ' + cacheDir + ' is not writable')
}
} Prevention
- Ensure the project directory and .cache are writable by the Node process.
- Free disk space before large builds.
- On Windows, add .cache to antivirus exclusions.
- Run gatsby clean between builds if you suspect corruption.
When it happens
Trigger: The fs.copy(srcDir, siteDir) or fs.ensureDir/fs.emptyDir for .cache throws -- due to permissions, disk space, file locks (Windows antivirus), or a corrupt/locked .cache directory.
Common situations: Windows with aggressive antivirus locking files in .cache. Read-only filesystem or insufficient permissions in the project directory. Disk full. A previous crashed build left .cache in a locked/corrupt state. Symlink or path-length limits on Windows.
Related errors
- Failed to read ${siteDir}/api-runner-ssr.js
- json-file-store failed to JSON.parse this string: `${dataStr
- Error loading a result for the page query in "${pagePath}".
- Error in gatsby-remark-code-repls plugin: cannot read
- Failed to write out requires
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/3383dbf6c53e1fdd.
Report an issue: GitHub.