Skip to content

Errors

How Coinbase failures surface and what to do at each step.

How errors surface

  1. Thrown errorsconnect(), startWithdrawal(), confirmWithdrawal(), getBalances(), etc. reject with ConnectSdkError (stable code).
  2. Events — e.g. coinbase:sessionExpired when the OAuth token dies mid-flow; oauth:error for popup failures.

Branch on code, not on message text:

ts
import {
  ConnectSdkError,
  ConnectSdkErrorCode,
} from '@swapped/connect-sdk';

try {
  await client.coinbase.startWithdrawal({
    /* amount, currency, name, … */
  });
} catch (error) {
  if (!(error instanceof ConnectSdkError)) {
    throw error;
  }

  switch (error.code) {
    case ConnectSdkErrorCode.COINBASE_COOLDOWN_ACTIVE: {
      const { remainingMs } = client.coinbase.getCooldown();
      // Disable start; show countdown
      break;
    }
    case ConnectSdkErrorCode.COINBASE_SESSION_EXPIRED:
    case ConnectSdkErrorCode.COINBASE_NOT_CONNECTED:
      await client.coinbase.connect();
      break;
    case ConnectSdkErrorCode.COINBASE_PASSKEY_NOT_SUPPORTED:
      // SMS / authenticator, not passkey
      break;
    case ConnectSdkErrorCode.COINBASE_INVALID_WITHDRAWAL_AMOUNT:
      // Field error on amount form
      break;
    case ConnectSdkErrorCode.SESSION_NOT_ACTIVE:
      await client.restartSession();
      break;
    default:
      // API_ERROR / unknown — generic retry
      break;
  }
}

client.on('coinbase:sessionExpired', () => {
  // Token died on the form — back to Connect
});

client.on('oauth:error', ({ error }) => {
  // Popup blocked / closed
});

When things fail in the flow

StepWhat goes wrongHow you see itWhat to do in UI
ConnectPopup blocked or closed earlyOAUTH_POPUP_*; also oauth:errorAllow popups; retry connect()
Connect / laterOAuth token expiredCOINBASE_SESSION_EXPIRED or coinbase:sessionExpiredCall connect() again
Any withdraw callNever connectedCOINBASE_NOT_CONNECTEDCall connect() first
Amount formAmount below min / invalid / non-viable above-spendablePrefer validateWithdrawalAmount for field UX; startWithdrawal auto-adjusts viable above-spendableField error or withdrawal callback
Start withdrawDouble-submit / retry too soonCOINBASE_COOLDOWN_ACTIVECooldown UI
Start / confirmPasskey-only confirmCOINBASE_PASSKEY_NOT_SUPPORTEDSMS / authenticator
Confirm 2FAWrong codeOften { status: 'requires2fa' } againKeep 2FA UI; show feedback; no cooldown
Confirm 2FANothing pendingCOINBASE_NO_ACTIVE_WITHDRAWALStart again
Start withdrawSession already completedSESSION_NOT_ACTIVErestartSession()

Wrong 2FA is usually not a hard error (returns requires2fa again). Cooldown never blocks confirm. In React, use is2faInvalid from useCoinbaseWithdrawal.

Prevent cooldown and amount errors in the UI:

ts
const { isInCooldown, remainingMs } = client.coinbase.getCooldown();
if (isInCooldown) {
  // disable Start
}

const validation = await client.coinbase.validateWithdrawalAmount({
  amount,
  balance,
  exchangeRate,
  symbol,
  network,
});
if (!validation.ok) {
  // show validation.reason — do not call startWithdrawal
}

Error code reference

CodeWhen it happensWhat to do
OAUTH_POPUP_BLOCKEDBrowser blocked login popupAllow popups; connect() again
OAUTH_POPUP_CLOSEDPopup closed earlyRetry connect()
COINBASE_NOT_CONNECTEDNo OAuth tokenCall connect()
COINBASE_SESSION_EXPIREDToken invalidReconnect; listen for coinbase:sessionExpired
COINBASE_INVALID_WITHDRAWAL_AMOUNTBelow min, invalid, or above spendable with no viable capValidate first; see withdrawal auto-adjust
COINBASE_COOLDOWN_ACTIVEStart during 30s cooldownWait; use getCooldown()
COINBASE_PASSKEY_NOT_SUPPORTEDPasskey confirmation requiredSMS / authenticator 2FA
COINBASE_NO_ACTIVE_WITHDRAWALConfirm with nothing pendingstartWithdrawal first
SESSION_NOT_ACTIVESession cannot accept a new paymentrestartSession()

Unmapped HTTP failures surface as API_ERROR. Show a retry message and keep the user on the same step when safe.