{"record":{"id":"36755492157af782","repo":"paperclipai/paperclip","slug":"user-authorization-required","errorCode":"user_authorization_required","errorMessage":"User authorization is required","messagePattern":"User authorization is required","errorType":"http","errorClass":"ToolGatewayHttpError","httpStatus":409,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":3406,"sourceCode":"          eq(companyMemberships.principalType, \"user\"),\n          eq(companyMemberships.principalId, userGrant.subjectUserId),\n          eq(companyMemberships.status, \"active\"),\n        )).limit(1);\n        if (!membership) {\n          throw new ToolGatewayHttpError(403, \"The delegated personal grant owner is not an active company member\", \"grant_owner_membership_inactive\", {\n            connectionId: connection.id,\n            grantId: userGrant.id,\n          });\n        }\n      }\n    }\n    const resolution = userGrant\n      ? \"user\"\n      : resolveCredentialGrantKind(connection.credentialPolicy, actingUserId, false);\n    if (resolution === \"user\" && userGrant) return userGrant;\n    if (resolution === \"user_authorization_required\") {\n      if (actingUserId) await createUserAuthorizationInteraction(session, connection, actingUserId);\n      throw new ToolGatewayHttpError(409, \"User authorization is required\", \"user_authorization_required\", {\n        connectionId: connection.id,\n        actingUserId,\n      });\n    }\n    return findOrganizationGrant();\n  }\n\n  async function resolveConnectedRemoteTool(session: ToolGatewaySession, tool: ToolGatewayDescriptor) {\n    if (tool.providerType !== \"mcp_remote_http\" || !tool.connectionId || !tool.catalogEntryId) {\n      throw new ToolGatewayHttpError(404, `Tool \"${tool.name}\" not found`, \"tool_not_found\");\n    }\n    const [entry] = await db\n      .select()\n      .from(toolCatalogEntries)\n      .where(and(\n        eq(toolCatalogEntries.id, tool.catalogEntryId),\n        eq(toolCatalogEntries.companyId, session.companyId),\n      ))","sourceCodeStart":3388,"sourceCodeEnd":3424,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/tool-gateway.ts#L3388-L3424","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Complete the user-authorization interaction: have the acting user connect/authorize the connection in the UI","Create a user-kind connection grant for the acting user via the connections authorization flow","Change the connection credentialPolicy to an organization credential if personal grants are not desired"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const grant = await findActiveUserGrant(connection.id, actingUserId);\nif (!grant && resolveCredentialGrantKind(connection.credentialPolicy, actingUserId, false) === 'user_authorization_required') {\n  await createUserAuthorizationInteraction(session, connection, actingUserId); // surface connect prompt first\n}","typeGuard":null,"tryCatchPattern":"try { await runTool(...) } catch (e) { if (e.code === 'user_authorization_required') { await promptUserToAuthorizeConnection(e.details.connectionId); } else throw e; }","preventionTips":["Check connection authorization status in the UI before launching runs that use it","Onboard users through the connection flow before assigning them agent work","Watch for pending user_authorization interactions before scheduling autonomous runs"],"tags":["authorization","oauth","user-interaction"],"backgroundTag":"authentication-required","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}