pnpm/pnpm · error · PnpmError

PROJECT_INACCESSIBLE

PROJECT_INACCESSIBLE

Error message

Cannot access registered project "${absoluteTarget}": ${message}

What it means

After resolving a project-registry entry's target (pnpm11/store/controller/src/storeController/projectRegistry.ts:90), fs.stat on the registered project directory failed with something other than ENOENT (which would clean up the stale entry). Errors like EACCES throw PROJECT_INACCESSIBLE because pruning based on unreadable projects could remove live data.

Source

Thrown at pnpm11/store/controller/src/storeController/projectRegistry.ts:90

      )
    }

    const absoluteTarget = path.isAbsolute(target) ? target : path.resolve(path.dirname(linkPath), target)

    // Check if project still exists
    try {
      await fs.stat(absoluteTarget)
      projects.push(absoluteTarget)
    } catch (err: unknown) {
      // Only clean up if project directory no longer exists
      if (util.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT') {
        await fs.unlink(linkPath)
        globalInfo(`Removed stale project registry entry: ${absoluteTarget}`)
        return
      }
      // Can't access project - throw error to prevent incorrect pruning
      const message = util.types.isNativeError(err) ? err.message : String(err)
      throw new PnpmError('PROJECT_INACCESSIBLE',
        `Cannot access registered project "${absoluteTarget}": ${message}`,
        {
          hint: `To remove this project from the registry, delete the symlink at:\n  ${linkPath}`,
        }
      )
    }
  }))

  return projects
}

View on GitHub (pinned to 6261b7f388)

Solutions

  1. Restore readable access to the project dir named in the message: `chmod -R a+rX <absoluteTarget>` or fix the mount.
  2. If the project is genuinely gone, remove the registry symlink at the linkPath given in the hint and re-run prune.
  3. Ensure the user running prune can stat every registered project (same UID/permissions model).

Example fix

// before
$ pnpm store prune
# ERR_PNPM_PROJECT_INACCESSIBLE: Cannot access registered project "/srv/app"

// after
$ chmod -R a+rX /srv/app        # or: rm <linkPath-from-hint>
$ pnpm store prune
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'

// every registered project target must be statable by this user before prune
function registeredProjectsAccessible (projects: string[]): boolean {
  return projects.every((dir) => {
    try {
      fs.statSync(dir)
      return true
    } catch (err: any) {
      return err.code === 'ENOENT' // gone is fine (auto-cleanup); EACCES is not
    }
  })
}

Try / catch

try {
  await store.prune()
} catch (err) {
  if ((err as NodeJS.ErrnoException).code === 'ERR_PNPM_PROJECT_INACCESSIBLE') {
    // hint names the linkPath; restore access to the project dir or rm the symlink
    throw err // do NOT auto-delete: that is exactly what the guard prevents
  }
  throw err
}

Prevention

When it happens

Trigger: `pnpm store prune` when a registered project directory exists but stat fails: permission denied on the project dir, an unreachable mount (stale NFS), or I/O errors - i.e. anything that is neither 'exists' nor 'gone'.

Common situations: Project directories owned by another user or root on shared machines; project on a network volume that is currently unmounted-but-erroring; restrictive ACLs created by backup tools.

Related errors


AI-assisted analysis of pnpm/pnpm@6261b7f388 (2026-08-17). Data as JSON: /api/errors/272bc3372f8f2203. Report an issue: GitHub.