gatsbyjs/gatsby · error

icon (${icon}) does not exist as defined in gatsby-config.js

Error message

icon (${icon}) does not exist as defined in gatsby-config.js. Make sure the file exists relative to the root of the site.

What it means

Thrown by gatsby-plugin-manifest's onPreInit/build path when an `icon` option is defined but doesIconExist(icon) returns false — the source icon file cannot be read. The plugin needs the source PNG/SVG to generate all derived icon sizes, so it aborts before invoking sharp.

Source

Thrown at packages/gatsby-plugin-manifest/src/gatsby-node.js:189

  // Determine destination path for icons.
  const paths = {}
  manifest.icons.forEach(icon => {
    const iconPath = path.join(`public`, path.dirname(icon.src))
    if (!paths[iconPath]) {
      const exists = fs.existsSync(iconPath)
      // create destination directory if it doesn't exist
      if (!exists) {
        fs.mkdirSync(iconPath, { recursive: true })
      }
      paths[iconPath] = true
    }
  })

  // Only auto-generate icons if a src icon is defined.
  if (typeof icon !== `undefined`) {
    // Check if the icon exists
    if (!doesIconExist(icon)) {
      throw new Error(
        `icon (${icon}) does not exist as defined in gatsby-config.js. Make sure the file exists relative to the root of the site.`
      )
    }

    const sharp = await getSharpInstance()
    const sharpIcon = sharp(icon)

    const metadata = await sharpIcon.metadata()

    if (metadata.width !== metadata.height) {
      reporter.warn(
        `The icon(${icon}) you provided to 'gatsby-plugin-manifest' is not square.\n` +
          `The icons we generate will be square and for the best results we recommend you provide a square icon.\n`
      )
    }

    // add cache busting
    const cacheMode =

View on GitHub (pinned to 8b06340921)

Solutions

  1. Create the icon file at the configured path (PNG recommended, at least 512x512, square).
  2. Correct the `icon` option to match the actual file path relative to the site root.
  3. If you do not want a custom icon, remove the `icon` option to skip auto-generation.
  4. Run `git lfs pull` if the asset is stored in LFS and CI fetches shallow checkouts.

Example fix

// before
{ resolve: 'gatsby-plugin-manifest', options: { icon: 'src/images/manifest-icon.png' } }
// after (path matches the existing file)
{ resolve: 'gatsby-plugin-manifest', options: { icon: 'src/images/icon.png' } }
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs')
if (options.icon && !fs.existsSync(options.icon)) {
  console.error(`icon file missing: ${options.icon}`)
}

Type guard

const iconFileExists = (icon?: string): boolean =>
  !icon || (typeof icon === 'string' && fs.existsSync(icon))

Prevention

When it happens

Trigger: Setting `icon: 'src/images/icon.png'` in gatsby-plugin-manifest options where that file does not exist relative to the site root; typo in the path; icon was deleted after config was written; path is absolute when relative is expected.

Common situations: Default config points at src/images/icon.png that the user never added; renamed the icon file; cloned a starter that omitted the image asset; CI checkout missing the asset due to .gitignore or LFS not pulled.

Related errors


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