yamadashy/repomix · error · RepomixError

Access denied. The repository might be private or you might

Error message

Access denied. The repository might be private or you might not have permission to access it.

What it means

A 403 from GitHub that is NOT a rate limit (X-RateLimit-Remaining is not '0') means GitHub refused authorization: the token or anonymous identity lacks permission for the repository. This is distinct from the rate-limit 403 and from 404.

Source

Thrown at src/core/git/gitHubArchiveApi.ts:56

 * Checks if a response indicates a GitHub API rate limit or error
 */
export const checkGitHubResponse = (response: Response): void => {
  if (response.status === 404) {
    throw new RepomixError(
      'Repository not found or is private. Please check the repository URL and your access permissions.',
    );
  }

  if (response.status === 403) {
    const rateLimitRemaining = response.headers.get('X-RateLimit-Remaining');
    if (rateLimitRemaining === '0') {
      const resetTime = response.headers.get('X-RateLimit-Reset');
      const resetDate = resetTime ? new Date(Number.parseInt(resetTime, 10) * 1000) : null;
      throw new RepomixError(
        `GitHub API rate limit exceeded. ${resetDate ? `Rate limit resets at ${resetDate.toISOString()}` : 'Please try again later.'}`,
      );
    }
    throw new RepomixError(
      'Access denied. The repository might be private or you might not have permission to access it.',
    );
  }

  if (response.status === 500 || response.status === 502 || response.status === 503 || response.status === 504) {
    throw new RepomixError('GitHub server error. Please try again later.');
  }

  if (!response.ok) {
    throw new RepomixError(`GitHub API error: ${response.status} ${response.statusText}`);
  }
};

View on GitHub (pinned to f465ad9093)

Solutions

  1. Check the token: `curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/user` — if it fails, generate a new token with repo read access.
  2. Grant the token the required scopes (classic: 'repo'; fine-grained: Contents: read for that repository).
  3. Authorize the token for the organization via SSO (Settings → Developer settings → token → 'Configure SSO').
  4. If an org IP allow-list is active, run from an allow-listed network or ask an admin to allow your IP.

Example fix

// before (token without repo scope)
export GITHUB_TOKEN=ghp_readOnlyPublicToken
npx repomix --remote https://github.com/myorg/private-repo
// after — regenerate with repo scope
export GITHUB_TOKEN=ghp_newTokenWithRepoScope
npx repomix --remote https://github.com/myorg/private-repo
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch('https://api.github.com/repos/owner/repo', {
  headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` }
});
if (res.status === 403) throw new Error('Token lacks permission for this repo; check scopes/SSO.');

Try / catch

try {
  await pack({ remote: url });
} catch (e) {
  if (e instanceof RepomixError && e.message.includes('Access denied')) {
    console.error('Fix token scopes/SSO or use an account with access to the repo.');
  } else throw e;
}

Prevention

When it happens

Trigger: GitHub API/archive request returns HTTP 403 with X-RateLimit-Remaining != '0' — the supplied GITHUB_TOKEN is invalid/expired/revoked, lacks the repo scope, or the repo belongs to an org with IP allow-list/SSO enforcement.

Common situations: Expired or rotated token still set in the environment; classic PAT without the 'repo' scope for private repos; fine-grained token without read contents permission; org SSO not authorized for the token; org IP allow-list blocking the runner.

Understand the failure class

Related errors


AI-assisted analysis of yamadashy/repomix@f465ad9093 (2026-08-29). Data as JSON: /api/errors/2b8e6dc55dc2f629. Report an issue: GitHub.