paperclipai/paperclip · error

GitHub inventory failed: the active installation has not…

Error message

GitHub inventory failed: the active installation has not granted the required access for: ${missingPermissions.join(", ")}. Approve the GitHub App permission update, then retry

What it means

After finding the single active installation, discoverDedicatedGitHubAppInstallation compares installation.permissions against REQUIRED_GITHUB_INSTALLATION_PERMISSIONS. Any permission whose granted access differs from the required value is collected; if the list is non-empty the error names the missing permissions and asks the installer to approve the pending permission update in GitHub.

Solutions

  1. Open the GitHub App settings page and approve the pending permission-change request for the installation, then retry.
  2. Have the installation owner visit https://github.com/settings/installations and accept the permission update for the app.
  3. If no pending request exists, bump the app manifest permissions to match REQUIRED_GITHUB_INSTALLATION_PERMISSIONS and re-request them from the installation owner.
  4. Reinstall the app on the target repositories with the current permission set granted.

Example fix

// before: app requested contents:read but installation granted contents: none
// missingPermissions = ['contents'] -> throws
// after: owner approves permission update so installation.permissions.contents === 'read'
// -> discovery returns installationId/accountId
Defensive patterns

Strategy: validation

Validate before calling

const inst = await getAppInstallation(octokit, installationId);
const missing = Object.entries(REQUIRED_GITHUB_INSTALLATION_PERMISSIONS)
  .filter(([p, access]) => inst.permissions?.[p] !== access)
  .map(([p]) => p);
if (missing.length) throw new Error(`Approve permission update for: ${missing.join(", ")}`);

Type guard

function hasRequiredPermissions(inst: { permissions?: Record<string, string> }): boolean {
  return Object.entries(REQUIRED_GITHUB_INSTALLATION_PERMISSIONS)
    .every(([p, a]) => inst.permissions?.[p] === a);
}

Try / catch

try {
  await discoverDedicatedGitHubAppInstallation(conn);
} catch (e) {
  if (e.message.includes("required access")) {
    // prompt user to approve the GitHub App permission update, then retry
  }
}

Prevention

When it happens

Trigger: Running GitHub chat inventory discovery when the app's saved installation permissions (installation.permissions[key]) do not equal the required access for one or more keys in REQUIRED_GITHUB_INSTALLATION_PERMISSIONS (e.g. after the app manifest added new permissions the owner has not accepted).

Common situations: Upgrading the GitHub App with new/changed permissions while the installation owner never approved the 'permission update' request email; installing an older version of the app whose permissions predate what inventory needs.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/78d67442323f0d1e. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/chat-provider-inventory.ts:317

      "GitHub inventory failed: install this GitHub App on the selected repositories first",
    );
  }
  if (active.length !== 1) {
    throw new Error(
      "GitHub inventory failed: this chat connection requires a dedicated GitHub App with exactly one active installation",
    );
  }
  const installation = active[0]!;
  const missingPermissions = Object.entries(
    REQUIRED_GITHUB_INSTALLATION_PERMISSIONS,
  )
    .filter(
      ([permission, access]) =>
        installation.permissions?.[permission] !== access,
    )
    .map(([permission]) => permission);
  if (missingPermissions.length > 0) {
    throw new Error(
      `GitHub inventory failed: the active installation has not granted the required access for: ${missingPermissions.join(", ")}. Approve the GitHub App permission update, then retry`,
    );
  }
  return {
    installationId: String(installation.id),
    accountId: Number.isFinite(installation.account?.id)
      ? String(installation.account?.id)
      : undefined,
    accountLabel:
      installation.account?.login ?? installation.account?.name ?? undefined,
    accountType: installation.account?.type,
    permissions: installation.permissions ?? {},
  };
}

View on GitHub (pinned to 01ad858492)