coleam00/Archon · error · AppPrivateKeyError

GITHUB_APP_ID is set but no private key was provided. Set GI

Error message

GITHUB_APP_ID is set but no private key was provided. Set GITHUB_APP_PRIVATE_KEY (inline PEM) or GITHUB_APP_PRIVATE_KEY_PATH (path to .pem).

What it means

loadAppPrivateKey requires a private key when GITHUB_APP_ID is set. If neither GITHUB_APP_PRIVATE_KEY (inline PEM) nor GITHUB_APP_PRIVATE_KEY_PATH is provided, it throws this AppPrivateKeyError listing both accepted variables.

Source

Thrown at packages/core/src/github-auth/private-key.ts:46

  const path = env.GITHUB_APP_PRIVATE_KEY_PATH;
  if (path?.trim()) {
    try {
      const raw = readFileSync(path, 'utf8');
      // Windows-edited .pem files arrive with CRLF; OpenSSL tolerates it but
      // some SSH-style key parsers don't. Normalise so downstream JWT signing
      // never has to care.
      const contents = raw.replace(/\r\n/g, '\n');
      assertLooksLikePem(contents);
      return contents;
    } catch (err) {
      if (err instanceof AppPrivateKeyError) throw err;
      throw new AppPrivateKeyError(
        `Failed to read GITHUB_APP_PRIVATE_KEY_PATH (${path}): ${(err as Error).message}`,
        err
      );
    }
  }
  throw new AppPrivateKeyError(
    'GITHUB_APP_ID is set but no private key was provided. ' +
      'Set GITHUB_APP_PRIVATE_KEY (inline PEM) or GITHUB_APP_PRIVATE_KEY_PATH (path to .pem).'
  );
}

function assertLooksLikePem(s: string): void {
  if (!s.includes('BEGIN') || !s.includes('PRIVATE KEY') || !s.includes('END')) {
    throw new AppPrivateKeyError(
      'Provided value is not a valid PEM-encoded private key (missing BEGIN/END markers).'
    );
  }
}

View on GitHub (pinned to 0773b97458)

Solutions

  1. Set GITHUB_APP_PRIVATE_KEY to the PEM contents (with \n escapes) or GITHUB_APP_PRIVATE_KEY_PATH to the .pem file
  2. Check the .env / secret manager actually exports the variable into the process
  3. Unset GITHUB_APP_ID if you do not intend to use GitHub App authentication at all

Example fix

// before
GITHUB_APP_ID=123456
// after
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY_PATH=/etc/archon/github-app.pem
Defensive patterns

Strategy: validation

Validate before calling

if (process.env.GITHUB_APP_ID && !process.env.GITHUB_APP_PRIVATE_KEY && !process.env.GITHUB_APP_PRIVATE_KEY_PATH) {
  throw new Error('GITHUB_APP_ID set without GITHUB_APP_PRIVATE_KEY or GITHUB_APP_PRIVATE_KEY_PATH');
}

Try / catch

try { const key = await loadAppPrivateKey(process.env); } catch (e) { if (e instanceof AppPrivateKeyError) failStartupWithConfigHelp(e); throw e; }

Prevention

When it happens

Trigger: Setting GITHUB_APP_ID but omitting both GITHUB_APP_PRIVATE_KEY and GITHUB_APP_PRIVATE_KEY_PATH in the environment, then calling loadAppPrivateKey.

Common situations: Partial migration from PAT auth to GitHub App auth; .env file missing the key vars; secret not injected in CI/container; typo in the env var name.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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