vercel/turborepo · error

unexpected error reading "package.json" at

Error message

unexpected error reading "package.json" at ${workspaceRoot}

What it means

The fallback branch of getPackageJson(): the thrown filesystem error had a code that was neither ENOENT nor EJSONPARSE (or had no code at all), so it is rethrown as a plain Error `unexpected error reading "package.json"` with no ConvertError type. It covers every other IO failure the OS can produce while reading the manifest.

Solutions

  1. Check the entry type: `ls -la package.json` must be a file, not a directory
  2. Fix read permissions: chmod 644 package.json (and chown if another user owns it)
  3. If running inside Docker/CI, verify the volume mount gives the runtime user read access
  4. Raise the file-descriptor limit (ulimit -n) if you suspect EMFILE
Defensive patterns

Strategy: try-catch

Validate before calling

import { statSync } from "node:fs";
const st = statSync(manifestPath); // throws ENOENT if missing — handle separately
if (!st.isFile()) throw new Error("package.json is a directory");
process.accessSync?.(manifestPath, fsConstants.R_OK); // verify readability

Type guard

function isUnexpectedReadError(e: unknown): e is Error {
  return e instanceof Error && !(typeof e === "object" && "type" in e);
}

Try / catch

try {
  await readWorkspace(args);
} catch (e) {
  // this branch throws a plain Error with no `type` — inspect the original
  // filesystem cause (permissions, EISDIR, EMFILE) and report it verbatim
  if (e instanceof Error && !("type" in e)) {
    log.error(`filesystem problem reading package.json: ${e.message}`);
  }
}

Prevention

When it happens

Trigger: EACCES/EPERM because package.json is not readable by the current user; EISDIR because package.json is actually a directory; EMFILE from file-descriptor exhaustion; exotic errors on network filesystems.

Common situations: Permission/ownership mismatches in Docker or CI volumes; a directory accidentally named package.json; processes leaking fds before the read; NFS/SMB mounts returning nonstandard errors.

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/40f83d757e29ab42. Report an issue: GitHub.

Appendix: source

Thrown at packages/turbo-workspaces/src/utils.ts:77

  try {
    return readJsonSync(packageJsonPath, "utf8") as PackageJson;
  } catch (err) {
    if (err && typeof err === "object" && "code" in err) {
      if (err.code === "ENOENT") {
        throw new ConvertError(`no "package.json" found at ${workspaceRoot}`, {
          type: "package_json-missing"
        });
      }
      if (err.code === "EJSONPARSE") {
        throw new ConvertError(
          `failed to parse "package.json" at ${workspaceRoot}`,
          {
            type: "package_json-parse_error"
          }
        );
      }
    }
    throw new Error(
      `unexpected error reading "package.json" at ${workspaceRoot}`
    );
  }
}

function getWorkspacePackageManager({
  workspaceRoot
}: {
  workspaceRoot: string;
}): PackageManager | undefined {
  const packageJson = getPackageJson({ workspaceRoot });
  const { packageManager, devEngines } = packageJson;
  if (packageManager) {
    try {
      const match = PACKAGE_MANAGER_REGEX.exec(packageManager);
      if (match) {
        const manager = match.groups?.manager;
        return isPackageManager(manager) ? manager : undefined;

View on GitHub (pinned to f9245100cf)