Significant-Gravitas/AutoGPT · warning · Error

Failed to start OAuth flow

Error message

Failed to start OAuth flow

What it means

Raised by reject_transfer when the transfer's status is already COMPLETED or REJECTED. Rejection is only possible while the transfer is still in a non-terminal state; once executed or rejected, the state machine refuses further transitions.

Source

Thrown at autogpt_platform/frontend/src/app/(no-navbar)/signup/useSignupPage.ts:79

        : `/auth/callback`;
      const fullCallbackUrl = `${window.location.origin}${callbackUrl}`;

      const response = await fetch("/api/auth/login/with-provider", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ provider, redirectTo: fullCallbackUrl }),
      });

      if (!response.ok) {
        const { error } = await response.json();

        if (error === "not_allowed") {
          setShowNotAllowedModal(true);
          setIsSigningUp(false);
          return;
        }

        throw new Error(error || "Failed to start OAuth flow");
      }

      const { url } = await response.json();
      if (url) window.location.href = url as string;
    } catch (error) {
      setIsGoogleLoading(false);
      setIsSigningUp(false);
      toast({
        title:
          error instanceof Error ? error.message : "Failed to start OAuth flow",
        variant: "destructive",
      });
    }
  }

  async function handleSignup(data: z.infer<typeof signupFormSchema>) {
    setIsLoading(true);

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Disable the reject action for rows with status COMPLETED or REJECTED and refresh state after any action.
  2. Catch the ValueError and re-fetch the transfer; if terminal, accept the outcome and update the UI.
  3. Map this to 409 Conflict in the API layer so clients can implement conditional retry logic.

Example fix

# before
await reject_transfer(tid, user_id, org_id)

# after
tr = await get_transfer(tid)
if tr.status in ("COMPLETED", "REJECTED"):
    return  # already terminal
await reject_transfer(tid, user_id, org_id)
Defensive patterns

Strategy: validation

Validate before calling

tr = await get_transfer(transfer_id)
if tr.status in ("COMPLETED", "REJECTED"):
    return  # terminal; cannot reject

Type guard

def is_rejectable(tr: TransferResponse) -> bool:
    return tr.status not in ("COMPLETED", "REJECTED")

Try / catch

try:
    await reject_transfer(tid, user_id, org_id)
except ValueError as e:
    if "Cannot reject" in str(e):
        await get_transfer(tid)  # accept current state
    else:
        raise

Prevention

When it happens

Trigger: POST reject on a transfer with status='COMPLETED' (already moved the resource) or status='REJECTED' (someone rejected first). Common with two admins acting concurrently, or an out-of-date transfer table.

Common situations: Race between two parties: one executes/approves-and-executes while the other clicks reject; retry of a reject that succeeded; UI allowing reject on terminal rows.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/df7f6ed607b81a81. Report an issue: GitHub.