paperclipai/paperclip · error · ToolGatewayHttpError

user_authorization_required

user_authorization_required

Error message

User authorization is required

What it means

The connection's credential policy resolved to 'user_authorization_required', meaning a human user's personal authorization is needed before the tool can run, and no user grant exists. If an actingUserId is present the gateway also creates a user-authorization interaction (asking the human to connect), then throws a 409.

Solutions

  1. Complete the user-authorization interaction: have the acting user connect/authorize the connection in the UI
  2. Create a user-kind connection grant for the acting user via the connections authorization flow
  3. Change the connection credentialPolicy to an organization credential if personal grants are not desired
Defensive patterns

Strategy: try-catch

Validate before calling

const grant = await findActiveUserGrant(connection.id, actingUserId);
if (!grant && resolveCredentialGrantKind(connection.credentialPolicy, actingUserId, false) === 'user_authorization_required') {
  await createUserAuthorizationInteraction(session, connection, actingUserId); // surface connect prompt first
}

Try / catch

try { await runTool(...) } catch (e) { if (e.code === 'user_authorization_required') { await promptUserToAuthorizeConnection(e.details.connectionId); } else throw e; }

Prevention

When it happens

Trigger: A tool on a connection whose credentialPolicy requires per-user authorization is invoked while resolveCredentialGrantKind returns 'user_authorization_required' — no active user-kind grant for the acting user and no delegation supplying userGrant.

Common situations: New user invoking an agent tool before linking their own OAuth account; token revoked/expired leaving no active grant; policy tightened from org-credential to user-credential after deployment.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/36755492157af782. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/tool-gateway.ts:4606

        }
      }
    }
    const resolution = userGrant
      ? "user"
      : resolveCredentialGrantKind(
          connection.credentialPolicy,
          actingUserId,
          false,
        );
    if (resolution === "user" && userGrant) return userGrant;
    if (resolution === "user_authorization_required") {
      if (actingUserId)
        await createUserAuthorizationInteraction(
          session,
          connection,
          actingUserId,
        );
      throw new ToolGatewayHttpError(
        409,
        "User authorization is required",
        "user_authorization_required",
        {
          connectionId: connection.id,
          actingUserId,
        },
      );
    }
    return findOrganizationGrant();
  }

  async function resolveConnectedRemoteTool(
    session: ToolGatewaySession,
    tool: ToolGatewayDescriptor,
  ) {
    if (
      tool.providerType !== "mcp_remote_http" ||

View on GitHub (pinned to 3f1d897a7c)