coleam00/Archon · error

EACCES

EACCES

Error message

Failed to read version: permission denied reading package.json

What it means

getDevVersion reads package.json to report the version; when the OS rejects the read with EACCES (permission denied), it throws this translated error instead of leaking the raw errno. The file exists but the current user/process lacks read permission on it or a parent directory.

Source

Thrown at packages/cli/src/commands/version.ts:44

  version: string;
}

/**
 * Get version for development mode (reads package.json)
 */
async function getDevVersion(): Promise<{ name: string; version: string }> {
  // Read root package.json (monorepo version), not the CLI package's own
  const pkgPath = join(SCRIPT_DIR, '../../../../package.json');

  let content: string;
  try {
    content = await readFile(pkgPath, 'utf-8');
  } catch (error) {
    const err = error as NodeJS.ErrnoException;
    if (err.code === 'ENOENT') {
      throw new Error('Failed to read version: package.json not found (bad installation?)');
    } else if (err.code === 'EACCES') {
      throw new Error('Failed to read version: permission denied reading package.json');
    }
    throw new Error(`Failed to read version: ${err.message}`);
  }

  let pkg: PackageJson;
  try {
    pkg = JSON.parse(content) as PackageJson;
  } catch (_error) {
    throw new Error('Failed to read version: package.json is malformed');
  }

  return { name: pkg.name, version: pkg.version };
}

/**
 * Get the git commit hash at runtime (dev mode).
 * Returns 'unknown' if git is unavailable or the command fails.
 */

View on GitHub (pinned to 0773b97458)

Solutions

  1. Check ownership/mode: `ls -l $(dirname <pkgPath>)/package.json` and `chmod a+r` it (or chown to your user).
  2. Reinstall without sudo into a user-writable prefix (e.g. bun/npm user-global paths) to avoid root-owned installs.
  3. If a security module (SELinux/AppArmor) denies the read, adjust policy or run from an allowed location.
  4. Run the CLI as the same user that performed the installation.

Example fix

// shell
// before: -rw------- root root package.json, running as user -> EACCES
sudo chown $(whoami) /path/to/install/package.json && chmod 644 /path/to/install/package.json
Defensive patterns

Strategy: validation

Validate before calling

import { accessSync, constants } from 'node:fs';
try {
  accessSync(pkgPath, constants.R_OK);
} catch {
  throw new Error(`Cannot read ${pkgPath} as user ${process.getuid?.()}: fix ownership/mode or reinstall without sudo`);
}

Try / catch

try {
  const info = await devInfo();
} catch (err) {
  if (err instanceof Error && err.message.includes('permission denied reading package.json')) {
    // chmod a+r the file / chown to the running user, or reinstall into a user prefix
  } else throw err;
}

Prevention

When it happens

Trigger: devInfo -> getDevVersion calls readFile(pkgPath) and Node rejects with code 'EACCES': file owned by another user (e.g. installed with sudo, run as normal user), restrictive mode bits (0000/0444 with different owner), no execute permission on a parent directory, or running inside a container/sandbox lacking read access to the install prefix.

Common situations: Global install performed with sudo creating root-owned files while later commands run unprivileged; corporate-managed machines locking Program Files/privileged prefixes; SELinux/AppArmor denying access; umask mishaps in a custom install script.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/6c00a2db6f078b4a. Report an issue: GitHub.