vercel/next.js · critical · Error

> Couldn't find any `pages` or `app` directory. Please creat

Error message

> Couldn't find any `pages` or `app` directory. Please create one under the project root

What it means

Thrown by findPagesDir() when neither a `pages` nor an `app` directory can be located under the project root (or ./src/). Next.js needs at least one routing directory to know what to build; with both absent it cannot infer routes and aborts before wasted work.

Source

Thrown at packages/next/src/lib/find-pages-dir.ts:23

  // prioritize ./${name} over ./src/${name}
  let curDir = path.join(dir, name)
  if (fs.existsSync(curDir)) return curDir

  curDir = path.join(dir, 'src', name)
  if (fs.existsSync(curDir)) return curDir

  return null
}

export function findPagesDir(dir: string): {
  pagesDir: string | undefined
  appDir: string | undefined
} {
  const pagesDir = findDir(dir, 'pages') || undefined
  const appDir = findDir(dir, 'app') || undefined

  if (appDir == null && pagesDir == null) {
    throw new Error(
      "> Couldn't find any `pages` or `app` directory. Please create one under the project root"
    )
  }

  if (pagesDir && appDir) {
    const pagesParent = path.dirname(pagesDir)
    const appParent = path.dirname(appDir)
    if (pagesParent !== appParent) {
      throw new Error(
        '> `pages` and `app` directories should be under the same folder'
      )
    }
  }

  return {
    pagesDir,
    appDir,
  }

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Create an `app/` (recommended) or `pages/` directory at the project root, or under `src/`.
  2. Confirm you are running the Next.js command from the directory that contains the routing folder, not a parent or sibling.
  3. In a monorepo, run the command via the package filter (`pnpm --filter=myapp dev`) or set cwd correctly.
  4. If using a custom src dir, ensure next.config.js srcDir (if set) and the actual folder layout agree.

Example fix

# before: project root has neither pages/ nor app/
ls # -> next.config.js package.json (no routing dir)
next dev  # error
# after
mkdir app && echo 'export default function Page(){return <p>hi</p>}' > app/page.tsx
next dev
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs'
import path from 'path'
function assertRoutingDirExists(root: string) {
  const candidates = ['pages', 'src/pages', 'app', 'src/app']
  if (!candidates.some((c) => fs.existsSync(path.join(root, c)))) {
    throw new Error('No pages/ or app/ directory found under ' + root)
  }
}

Type guard

function hasRoutingDir(root: string): boolean {
  return ['pages','src/pages','app','src/app'].some((c) =>
    fs.existsSync(path.join(root, c)))
}

Prevention

When it happens

Trigger: Running `next dev`/`next build` in a directory that has no pages/ or app/ folder (and no src/pages or src/app). The lookup checks ./pages, ./src/pages, ./app, ./src/app in that priority.

Common situations: Wrong working directory (running Next from a parent folder); a fresh project where the routing directory was gitignored or never created; a monorepo where the command is executed at the workspace root rather than the app package; or after renaming pages/ to routes/ by mistake.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/b3534a91e7c780a5. Report an issue: GitHub.