paperclipai/paperclip · error · GitHubAttachmentUnavailableError

github_attachment_canonical_api_request_failed

Error message

github_attachment_canonical_api_request_failed

What it means

The canonical GitHub API request inside resolveGitHubAttachmentComment is wrapped in try/catch; any failure from the octokit request (network error, HTTP error, abort) is rethrown as GitHubAttachmentUnavailableError whose code comes from githubAttachmentDiagnosticCode(error) or, if no specific diagnostic maps, the generic 'github_attachment_canonical_api_request_failed'. Octokit error payloads (headers, HTML bodies) are deliberately stripped to keep them out of logs and durable ingress.

Source

Thrown at server/src/services/chat-sdk-runtime.ts:2863

        `GET ${request.url}`,
        {
          headers: {
            accept: request.accept,
            "x-github-api-version": "2022-11-28",
          },
          request: {
            signal,
            redirect: "manual",
            fetch: githubAttachmentCommentFetch(request, signal),
          },
        },
      );
      signal.throwIfAborted();
      return result.data;
    } catch (error) {
      // Octokit errors can carry request headers or authenticated HTML. Neither
      // belongs in adapter logs, durable ingress, nor agent-visible results.
      throw new GitHubAttachmentUnavailableError(
        githubAttachmentDiagnosticCode(error) ??
          "github_attachment_canonical_api_request_failed",
      );
    }
  }

  /**
   * Rebuild an adapter-authenticated download closure after process restart.
   * Invalid, cross-provider, or no-longer-safe descriptors fail closed.
   */
  rehydrateAttachment(
    descriptor: unknown,
    source?: ChatSdkAttachmentSource,
  ): Attachment | null {
    if (
      this.provider === "microsoft-teams" &&
      isRecord(descriptor) &&
      isRecord(descriptor.locator) &&

View on GitHub (pinned to 01ad858492)

Solutions

  1. Read the specific diagnostic code if present; only fall back to treating this as a generic GitHub API failure
  2. Check GitHub App installation status and token freshness; reinstall/refresh the installation if 401/403
  3. Check rate-limit headers and back off before retrying
  4. Verify the request.url still points to an existing GitHub resource and retry with a fresh signal

Example fix

// before
const data = await runtime.resolveGitHubAttachmentComment(request, signal);
// after
try {
  const data = await runtime.resolveGitHubAttachmentComment(request, signal);
} catch (e) {
  if ((e as Error).message === 'github_attachment_canonical_api_request_failed') {
    // inspect GitHub App installation + rate limits, then retry with backoff
  }
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight: ensure installation token is fresh and url is a valid api.github.com path
if (!request.url.startsWith('https://api.github.com/')) throw new Error('bad github url');

Try / catch

try { return await runtime.resolveGitHubAttachmentComment(request, signal); } catch (e) { if ((e as Error).message === 'github_attachment_canonical_api_request_failed') { await backoff(); return runtime.resolveGitHubAttachmentComment(request, signal); } throw e; }

Prevention

When it happens

Trigger: The underlying GET request.url via (adapter as GitHubAdapter).octokit throws: rate limit (403), expired/invalid installation token (401), resource gone (404/410), network failure, or signal abort; githubAttachmentDiagnosticCode does not classify it so the generic code is used.

Common situations: GitHub API rate limit exceeded for the installation; GitHub App installation token expired or revoked; repository/issue deleted; transient network outage or timeout during attachment resolution.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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