gatsbyjs/gatsby · error

starter ${starterPath} doesn't exist

Error message

starter ${starterPath} doesn't exist

What it means

Thrown by the `copy` helper in gatsby-cli's init-starter after ensureDir succeeds but fs.existsSync(starterPath) returns false. It guards the local-starter branch of `gatsby new <site> <starter>` where the starter argument is treated as a filesystem path rather than a GitHub repo shorthand.

Source

Thrown at packages/gatsby-cli/src/init-starter.ts:140

  } finally {
    process.chdir(prevDir)
  }
}

const ignored = (path: string): boolean =>
  !/^\.(git|hg)$/.test(sysPath.basename(path))

// Copy starter from file system.
const copy = async (
  starterPath: string,
  rootPath: string
): Promise<boolean> => {
  // Chmod with 755.
  // 493 = parseInt('755', 8)
  await fs.ensureDir(rootPath, { mode: 493 })

  if (!existsSync(starterPath)) {
    throw new Error(`starter ${starterPath} doesn't exist`)
  }

  if (starterPath === `.`) {
    throw new Error(
      `You can't create a starter from the existing directory. If you want to
      create a new site in the current directory, the trailing dot isn't
      necessary. If you want to create a new site from a local starter, run
      something like "gatsby new new-gatsby-site ../my-gatsby-starter"`
    )
  }

  report.info(`Creating new site from local starter: ${starterPath}`)

  report.log(`Copying local starter to ${rootPath} ...`)

  await fs.copy(starterPath, rootPath, { filter: ignored })

  report.success(`Created starter directory layout`)

View on GitHub (pinned to 8b06340921)

Solutions

  1. Confirm the path exists: `ls -la <starterPath>` from the same cwd where `gatsby new` runs.
  2. Use an absolute path to remove cwd ambiguity, or `cd` to the parent of the starter first.
  3. If you meant a remote starter, use the `org/repo` shorthand (e.g. gatsbyjs/gatsby-starter-blog) instead of a filesystem path.
  4. Re-clone the starter repo locally if it was removed.

Example fix

# before
gatsby new my-site ./stater-typo
# after
gatsby new my-site /abs/path/to/gatsby-starter-blog
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs')
if (fs.existsSync(starterPath) === false) {
  console.error(`No local starter at ${starterPath}; aborting`)
  process.exit(1)
}

Type guard

const isExistingPath = (p: string): boolean => { try { return fs.existsSync(p) } catch { return false } }

Prevention

When it happens

Trigger: Running `gatsby new my-site ./nonexistent` or `gatsby new my-site ../missing-starter` so the resolved starterPath does not exist on disk; passing a relative path resolved against an unexpected cwd; a typo in the starter directory name.

Common situations: User intends a local starter but mistypes the path; running `gatsby new` from a scripts/ directory so a relative ../my-starter resolves wrong; the starter directory was deleted or never cloned; shell tab-completion inserted a wrong segment.

Related errors


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