{"record":{"id":"1bb49b6bf78591f3","repo":"Significant-Gravitas/AutoGPT","slug":"failed-to-start-oauth-flow","errorCode":null,"errorMessage":"Failed to start OAuth flow","messagePattern":"Failed to start OAuth flow","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"autogpt_platform/frontend/src/app/(no-navbar)/login/useLoginPage.ts","lineNumber":70,"sourceCode":"    setIsGoogleLoading(true);\n    setIsLoggingIn(true);\n\n    try {\n      // Include next URL in OAuth flow if present\n      const callbackUrl = nextUrl\n        ? `/auth/callback?next=${encodeURIComponent(nextUrl)}`\n        : `/auth/callback`;\n      const fullCallbackUrl = `${window.location.origin}${callbackUrl}`;\n\n      const response = await fetch(\"/api/auth/login/with-provider\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({ provider, redirectTo: fullCallbackUrl }),\n      });\n\n      if (!response.ok) {\n        const { error } = await response.json();\n        throw new Error(error || \"Failed to start OAuth flow\");\n      }\n\n      const { url } = await response.json();\n      if (url) window.location.href = url as string;\n    } catch (error) {\n      setIsGoogleLoading(false);\n      setIsLoggingIn(false);\n      setFeedback(\n        error instanceof Error ? error.message : \"Failed to start OAuth flow\",\n      );\n    }\n  }\n\n  async function handleLogin(data: z.infer<typeof loginFormSchema>) {\n    setIsLoading(true);\n    setIsLoggingIn(true);\n\n    if (data.email.includes(\"@agpt.co\")) {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/frontend/src/app/(no-navbar)/login/useLoginPage.ts#L52-L88","documentation":"Raised by approve_transfer when the caller's active org matches neither the transfer's sourceOrganizationId nor its targetOrganizationId. Only the two participating orgs may approve; every other org is rejected with a ValueError.","triggerScenarios":"Thrown at autogpt_platform/frontend/src/app/(no-navbar)/login/useLoginPage.ts:70 when the library encounters an invalid state.","commonSituations":"Multi-org users forgetting to switch active org in the UI; frontend sending a stale active-org ID after the user switched orgs; copying a transfer URL and approving from an unrelated account.","solutions":["Verify the active org matches one of the transfer's parties (source/target) before calling approve; prompt the user to switch org if they belong to one of them.","Ensure the frontend passes the currently selected org consistently on every transfers call.","Surface which orgs are parties in the error detail so the user knows which org to switch to."],"exampleFix":"# before\nawait approve_transfer(tid, user_id, active_org_id)\n\n# after\ntr = await get_transfer(tid)\nif active_org_id not in (tr.source_org_id, tr.target_org_id):\n    raise PermissionError(\"Switch to a participating org to approve\")\nawait approve_transfer(tid, user_id, active_org_id)","handlingStrategy":"type-guard","validationCode":"tr = await get_transfer(transfer_id)\nassert org_id in (tr.source_org_id, tr.target_org_id), \"Switch to a participating org\"","typeGuard":"def org_is_party(tr: TransferResponse, org_id: str) -> bool:\n    return org_id in (tr.source_org_id, tr.target_org_id)","tryCatchPattern":"try:\n    await approve_transfer(tid, user_id, org_id)\nexcept ValueError as e:\n    if \"not a party\" in str(e):\n        prompt_org_switch(tr)\n    else:\n        raise","preventionTips":["Always send the currently selected org with transfers calls","Prompt an org switch when the user belongs to a party org but has another active","Show party org names in the transfer list"],"tags":["transfers","authorization","multi-org"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}