vercel/next.js · error · Error

Specified distDir is not a string, found type "${typeof valu

Error message

Specified distDir is not a string, found type "${typeof value}"

What it means

Thrown during config normalization when the distDir option is present but not a string. distDir tells Next.js where to emit the build output (.next by default); it must be a string path. Any other type (number, object, array, boolean) is rejected outright before further validation (reserved-name, empty-string checks).

Source

Thrown at packages/next/src/server/config.ts:345

      )
    }
    if (typeof userConfig.trailingSlash === 'undefined') {
      userConfig.trailingSlash = (userConfig as any).exportTrailingSlash
    }
    delete (userConfig as any).exportTrailingSlash
  }

  const config = Object.keys(userConfig).reduce<{ [key: string]: any }>(
    (currentConfig, key) => {
      const value = (userConfig as any)[key]

      if (value === undefined || value === null) {
        return currentConfig
      }

      if (key === 'distDir') {
        if (typeof value !== 'string') {
          throw new Error(
            `Specified distDir is not a string, found type "${typeof value}"`
          )
        }
        const userDistDir = value.trim()

        // don't allow public as the distDir as this is a reserved folder for
        // public files
        if (userDistDir === 'public') {
          throw new Error(
            `The 'public' directory is reserved in Next.js and can not be set as the 'distDir'. https://nextjs.org/docs/messages/can-not-output-to-public`
          )
        }
        // make sure distDir isn't an empty string as it can result in the provided
        // directory being deleted in development mode
        if (userDistDir.length === 0) {
          throw new Error(
            `Invalid distDir provided, distDir can not be an empty string. Please remove this config or set it to undefined`
          )

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Set distDir to a string path, e.g. '.next' or 'build'.
  2. If deriving from an env var, coerce/guard: distDir: process.env.OUT_DIR || '.next'.
  3. Remove the distDir key entirely to use the default '.next'.
  4. Verify the config file does not assign a non-string to distDir under any branch.

Example fix

// before
// module.exports = { distDir: process.env.OUT_DIR } // OUT_DIR unset -> undefined

// after
// module.exports = { distDir: process.env.OUT_DIR || '.next' }
Defensive patterns

Strategy: type-guard

Validate before calling

// Coerce distDir to a safe string default.
const raw = (config as any).distDir
if (raw !== undefined && typeof raw !== 'string') {
  throw new Error('distDir must be a string')
}
config.distDir = typeof raw === 'string' ? raw : '.next'

Type guard

function isStringDistDir(v: unknown): v is string | undefined {
  return v === undefined || typeof v === 'string'
}

Prevention

When it happens

Trigger: next.config.js sets distDir to a non-string value (e.g. distDir: true, distDir: 123, or a variable that resolved to undefined-ish/non-string). The reduce loop at config.ts:343 checks typeof value !== 'string' and throws.

Common situations: Programmatic config computing distDir from an env var that is undefined (resulting in a non-string); accidentally assigning an object; typos; a conditional that yields a boolean.

Related errors


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