coleam00/Archon · error

Authentication failed for ${owner}/${repo}. ${authHint}

Error message

Authentication failed for ${owner}/${repo}. ${authHint}

What it means

Thrown by GitHubAdapter.ensureRepoReady when cloneRepository returns code 'permission_denied': the repository exists but the credentials used for the clone were rejected or lack read access. The message includes an auth-specific hint depending on whether Archon is running in GitHub App mode or PAT mode (GITHUB_TOKEN).

Source

Thrown at packages/adapters/src/forge/github/adapter.ts:766

      ghToken ? { token: ghToken } : undefined
    );

    if (!cloneResult.ok) {
      getLog().error(
        { error: cloneResult.error, owner, repo, repoPath },
        'github.repo_clone_failed'
      );

      if (cloneResult.error.code === 'not_a_repo') {
        throw new Error(
          `Repository ${owner}/${repo} not found or is private. Check repository access.`
        );
      } else if (cloneResult.error.code === 'permission_denied') {
        const authHint =
          this.auth.kind === 'app'
            ? 'Check that the Archon GitHub App is installed on the org and has the Contents:Read permission.'
            : 'Check GITHUB_TOKEN permissions.';
        throw new Error(`Authentication failed for ${owner}/${repo}. ${authHint}`);
      }
      throw new Error(
        `Failed to clone ${owner}/${repo}: ${'message' in cloneResult.error ? cloneResult.error.message : cloneResult.error.code}`
      );
    }

    await addSafeDirectory(toRepoPath(repoPath));

    // App mode: install the git credential helper on the newly cloned worktree
    // so workflows that outlive the 1h installation-token expiry can refresh
    // credentials in-place. Non-fatal — workflows that complete in <1h still
    // succeed via the URL-embedded token from the clone above. The result
    // discriminator tells us whether the install actually happened so we
    // don't log a false "installed" line in builds where the helper script
    // isn't on disk.
    if (this.auth.kind === 'app') {
      const result = await installCredentialHelper(repoPath);
      switch (result.kind) {

View on GitHub (pinned to 0773b97458)

Solutions

  1. In App mode: verify the Archon GitHub App is installed on the org and granted Contents (Read) permission, then retry so a fresh ~1h installation token is minted.
  2. In PAT mode: check GITHUB_TOKEN/GH_TOKEN is set, unexpired, and has read access to the repository (classic PAT with 'repo' scope or fine-grained PAT covering the repo).
  3. Test the credential manually: git clone https://github.com/${owner}/${repo}.git with the same token to reproduce the denial.
  4. Confirm app installation includes the specific repository (not just selected repos that exclude it).

Example fix

// before
export GITHUB_TOKEN=ghp_expired_token
// after: fresh token with repo read access
export GITHUB_TOKEN=github_pat_11AAAA..._with_contents_read
Defensive patterns

Strategy: validation

Validate before calling

// Check the token can read the repo before invoking adapter flows
const res = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {
  headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` },
});
if (!res.ok) throw new Error(`Token cannot read ${owner}/${repo}: HTTP ${res.status}`);

Try / catch

try {
  await adapter.handleWebhook(payload);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Authentication failed for')) {
    // rotate token / verify App installation before retrying
  }
}

Prevention

When it happens

Trigger: handleWebhook -> ensureRepoReady clones with an installation token or GITHUB_TOKEN/GH_TOKEN that is invalid, expired, or lacks Contents:Read on the target repo.

Common situations: Expired/rotated GITHUB_TOKEN; fine-grained PAT not granted to the repo; GitHub App installed org-wide but without Contents:Read permission; token scoped to a different org; app installed on the org but the repo excluded.

Understand the failure class

Related errors


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