vercel/next.js · error

Failed to find package manager

Error message

Failed to find package manager

What it means

`handle-package.ts`'s `uninstallPackage` defaults the manager via `getPkgManager(process.cwd())`; if that returns a falsy value it throws this. Note `getPkgManager` itself has a `catch { return 'npm' }` fallback, so in practice it almost never returns falsy — this throw guards the case where a caller passes an explicit `undefined`/`null` *and* the lookup returns undefined. The same guard exists in `installPackages`. It signals the codemod could not determine which package manager to drive.

Source

Thrown at packages/next-codemod/lib/handle-package.ts:106

        case 'package-lock.json':
          return 'npm'
        default:
          return 'npm'
      }
    }
    // No lock file found, default to npm
    return 'npm'
  } catch {
    return 'npm'
  }
}

export function uninstallPackage(
  packageToUninstall: string,
  pkgManager?: PackageManager
) {
  pkgManager ??= getPkgManager(process.cwd())
  if (!pkgManager) throw new Error('Failed to find package manager')

  let command = 'uninstall'
  if (pkgManager === 'yarn') {
    command = 'remove'
  }

  try {
    execa.sync(pkgManager, [command, packageToUninstall], {
      stdio: 'inherit',
      shell: true,
    })
  } catch (error) {
    throw new Error(
      `Failed to uninstall "${packageToUninstall}". Please uninstall it manually.`,
      { cause: error }
    )
  }
}

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Run the codemod from a directory that contains (or is under) a lockfile (package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lock/bun.lockb).
  2. Pass an explicit `packageManager` argument to `uninstallPackage`/`installPackages` so the lookup is skipped.
  3. Ensure `npm_config_user_agent` is set (running under npm/pnpm/yarn/bun normally sets it).
  4. Check read permissions on the project directory and lockfiles.

Example fix

// before
uninstallPackage('old-pkg') // throws if lookup returns undefined

// after — pass manager explicitly
import { getPkgManager } from '@next/codemod/lib/handle-package'
uninstallPackage('old-pkg', getPkgManager(process.cwd()) ?? 'npm')
Defensive patterns

Strategy: validation

Validate before calling

import { getPkgManager } from '@next/codemod/lib/handle-package'
const pm = getPkgManager(process.cwd()) ?? 'npm'
uninstallPackage('old-pkg', pm)

Type guard

function isPackageManager(pm: unknown): pm is 'npm'|'pnpm'|'yarn'|'bun' {
  return typeof pm === 'string' && ['npm','pnpm','yarn','bun'].includes(pm)
}

Try / catch

try {
  uninstallPackage(pkg)
} catch (e) {
  if (/Failed to find package manager/.test(e.message)) {
    uninstallPackage(pkg, 'npm') // explicit fallback
  } else throw e
}

Prevention

When it happens

Trigger: A codemod that uninstalls/installs a package calls `uninstallPackage(name)` (or `installPackages`) when `getPkgManager` somehow returned undefined — e.g. an exceptional environment where both `npm_config_user_agent` is unset and `find-up` for every lockfile threw, bypassing the catch fallback, or a caller passed `packageManager: undefined` explicitly while cwd is unreadable.

Common situations: Custom codemod invoking these helpers from an unusual cwd; test mocks that stub getPkgManager to return undefined; file-system permission errors preventing lockfile discovery.

Related errors


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