paperclipai/paperclip · error · ToolGatewayHttpError
github_identity_unavailable
github_identity_unavailable
Error message
${selected.error ?? "No GitHub identity connected"} What it means
The Paperclip tool gateway resolves a managed GitHub identity for the session before dispatching a call through a connection whose source template is "github". If resolveManagedGitHubIdentitySelection finds no identity grant for the company/responsible user (and standing delegation is disallowed), the gateway aborts with HTTP 409 and code github_identity_unavailable. It means the agent session has no usable GitHub identity to act as.
Solutions
- Connect a managed GitHub identity for the company/responsible user via the Apps catalog GitHub connection flow before dispatching the tool call.
- Verify the responsibleUserId on the session actually has a linked GitHub grant; re-link if it was revoked.
- If delegation is appropriate, allow standing delegation in resolveManagedGitHubIdentitySelection or grant the agent its own identity.
- Check the message body for the underlying selected.error detail to distinguish 'not connected' from 'connected but not selectable'.
- Return a clear operator action in the UI: prompt the responsible user to connect GitHub under Apps.
Example fix
// before
const res = await gateway.call(session, "github_list_issues", args); // throws 409
// after
const sel = await resolveManagedGitHubIdentitySelection(db, session.companyId, { agentId: session.agentId, responsibleUserId: session.responsibleUserId, allowStandingDelegation: false });
if (!sel.grant) throw new Error(`Connect GitHub first: ${sel.error}`);
const res = await gateway.call(session, "github_list_issues", args); Defensive patterns
Strategy: validation
When it happens
Trigger: An agent invokes a GitHub-backed tool via the gateway where toolConnections row has config.sourceTemplateKey (or transportConfig.sourceTemplateKey) === "github", and resolveManagedGitHubIdentitySelection returns no grant: no identity is connected for the responsible user, no agent-scoped grant exists, and allowStandingDelegation is false so delegation cannot substitute. selected.error is included in the message when present.
Common situations: Agent tries a GitHub tool before anyone connected GitHub in Apps/connections for that company; the responsible user changed to someone without a linked GitHub identity; a grant was revoked/deleted; org setup expects standing delegation but the call path passes allowStandingDelegation:false.
Related errors
- ambiguous_personal_grant
- github_tool_unavailable
- grant_audience_denied
- grant_owner_membership_inactive
- grant_owner_missing
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/27e587293c85dcc0.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/tool-gateway.ts:2653
eq(toolConnections.id, tool.connectionId),
eq(toolConnections.companyId, session.companyId),
),
);
if (
connection?.config.sourceTemplateKey === "github" ||
connection?.transportConfig?.sourceTemplateKey === "github"
) {
let selected = await resolveManagedGitHubIdentitySelection(
db,
session.companyId,
{
agentId: session.agentId,
responsibleUserId: session.responsibleUserId,
allowStandingDelegation: false,
},
);
if (!selected.grant)
throw new ToolGatewayHttpError(
409,
selected.error ?? "No GitHub identity connected",
"github_identity_unavailable",
);
const original = selected.grant;
// Acquire before policy evaluation or dispatch. An alternate connection
// gets its own catalog descriptor and policy checks; never replay a call.
for (let attempt = 0; attempt < 2; attempt += 1) {
const grant = selected.grant!;
const target = connectedTools.find(
(candidate) =>
candidate.connectionId === grant.connectionId &&
candidate.upstreamToolName === tool.upstreamToolName &&
candidate.providerType === tool.providerType,
);
if (!target)
throw new ToolGatewayHttpError(
404,View on GitHub (pinned to 3f1d897a7c)