paperclipai/paperclip · error
GitHub inventory failed: installation token was missing
Error message
GitHub inventory failed: installation token was missing
What it means
Thrown by listGitHubInstallationRepositories when the GitHub App installation-token exchange succeeded at HTTP level but the response body contains no 'token' field. The installation token is required for all subsequent /installation/repositories page fetches, so without it the inventory cannot proceed.
Source
Thrown at server/src/services/chat-provider-inventory.ts:189
appJwt: string;
installationId: string;
fetch: typeof globalThis.fetch;
}): Promise<ChatProviderInventoryResult> {
const headers = {
accept: "application/vnd.github+json",
authorization: `Bearer ${input.appJwt}`,
"x-github-api-version": "2022-11-28",
};
const tokenResponse = await input.fetch(
`https://api.github.com/app/installations/${encodeURIComponent(input.installationId)}/access_tokens`,
{ method: "POST", headers, signal: githubRequestSignal() },
);
const tokenBody = await jsonResponse<{ token?: string; message?: string }>(
tokenResponse,
"GitHub",
);
if (!tokenBody.token)
throw new Error("GitHub inventory failed: installation token was missing");
const resources: ChatProviderResourceInventoryItem[] = [];
let page = 1;
try {
while (true) {
const url = new URL("https://api.github.com/installation/repositories");
url.searchParams.set("per_page", "100");
url.searchParams.set("page", String(page));
const response = await input.fetch(url, {
headers: {
accept: "application/vnd.github+json",
authorization: `Bearer ${tokenBody.token}`,
"x-github-api-version": "2022-11-28",
},
signal: githubRequestSignal(),
});
const body = await jsonResponse<{
repositories?: Array<{View on GitHub (pinned to 01ad858492)
Solutions
- Retry the repository inventory; a transient malformed token response usually resolves on retry.
- Reconnect the GitHub App connection to restart the auth flow with fresh App credentials.
- Confirm the App is not suspended on GitHub (suspended apps cannot mint installation tokens).
- Bypass or inspect any proxy between the server and api.github.com for body rewriting.
Defensive patterns
Strategy: retry
Validate before calling
// Before inventory, confirm the App can mint tokens (not suspended):
const inst = await gh.request('GET /app/installations');
if (!inst.data.some(i => !i.suspended_at)) {
throw new Error('No active installation; install/reactivate the App first');
} Type guard
function hasInstallationToken(b: { token?: string; message?: string }): b is { token: string; message?: string } {
return typeof b.token === 'string' && b.token.length > 0;
} Try / catch
try { const repos = await listGitHubInstallationRepositories(input); }
catch (e) {
if (e.message.includes('installation token was missing')) {
await retryWithBackoff(() => listGitHubInstallationRepositories(input), 2);
// if persistent, force reconnect to restart token exchange
}
} Prevention
- Ensure the App is active and unsuspended before inventory runs.
- Retry transient malformed token responses; escalate to reconnect if repeated.
- Avoid proxies that mutate GitHub API response bodies.
- Monitor GitHub API incidents affecting token minting.
When it happens
Trigger: The token-access response (POST /app/installations/{id}/access_tokens) parses OK but tokenBody.token is undefined — e.g. GitHub returned an unexpected shape, an error envelope with only 'message', or a proxied/mutated response.
Common situations: GitHub API partial outage returning an error envelope with 200; proxy rewriting the response; App suspended between auth steps; response contract drift from an API gateway in front of the server.
Related errors
- ${provider} inventory failed: ${message}
- GitHub inventory failed: install this GitHub App on the sele
- GitHub inventory failed: this chat connection requires a ded
- ${options.errorLabel} decision predicate failed: ${detail}
- ${options.errorLabel} decision predicate exited 0 (expected
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/859f31dc27420850.
Report an issue: GitHub.