benweet/stackedit · error · Error

The authorize window was blocked.

Error message

The authorize window was blocked.

What it means

startOauth2 opens the provider's authorize URL in a popup tab (or iframe when configured). If window.open() returns null the popup was blocked, so the OAuth flow cannot continue and the error is thrown at src/services/networkSvc.js:168. Browsers block window.open calls that are not the direct result of a user gesture, and they also block any popup after an async await delay.

Source

Thrown at src/services/networkSvc.js:168

      const state = utils.uid();
      const authorizeUrl = utils.addQueryParams(url, {
        ...params,
        state,
        redirect_uri: constants.oauth2RedirectUri,
      });

      let iframeElt;
      let wnd;
      if (silent) {
        // Use an iframe as wnd for silent mode
        iframeElt = utils.createHiddenIframe(authorizeUrl);
        document.body.appendChild(iframeElt);
        wnd = iframeElt.contentWindow;
      } else {
        // Open a tab otherwise
        wnd = window.open(authorizeUrl);
        if (!wnd) {
          throw new Error('The authorize window was blocked.');
        }
      }

      let checkClosedInterval;
      let closeTimeout;
      let msgHandler;
      try {
        return await new Promise((resolve, reject) => {
          if (silent) {
            iframeElt.onerror = () => {
              reject(new Error('Unknown error.'));
            };
            closeTimeout = setTimeout(() => {
              if (!reattempt) {
                reject(new Error('REATTEMPT'));
              } else {
                isConnectionDown = true;
                store.commit('setOffline', true);

View on GitHub (pinned to 6dce2a5e36)

Solutions

  1. Trigger startOauth2 synchronously from the click handler, or open a blank window before the await and set its location to authorizeUrl afterwards.
  2. Whitelist the site in the browser's popup blocker settings and retry.
  3. Retry the authorization action with a direct user click.
  4. Fall back to a full-page redirect to the authorize URL instead of a popup.

Example fix

// before
const accessToken = await someAsyncPreStep();
wnd = window.open(authorizeUrl);
// after
const wnd = window.open('', '_blank'); // inside the click handler, keeps user gesture
const accessToken = await someAsyncPreStep();
wnd.location.href = authorizeUrl;
Defensive patterns

Strategy: try-catch

Validate before calling

function popupsLikelyAllowed() {
  const test = window.open('', '_blank');
  if (test) { test.close(); return true; }
  return false;
}

Type guard

function openedWindow(wnd) {
  return wnd !== null && typeof wnd === 'object' && !wnd.closed;
}

Try / catch

try {
  await networkSvc.startOauth2(...);
} catch (err) {
  if (/blocked/i.test(err.message)) {
    showRetryBanner('Popup blocked — allow popups for this site and click Authorize again.');
  }
}

Prevention

When it happens

Trigger: Calling startOauth2 after an await or timer such that window.open(authorizeUrl) runs outside a user-gesture context; popup blocker blocking the tab; iframe path not taken and window.open returns null.

Common situations: Users click 'Authorize', the token request await resolves too slowly, then the popup opens and is blocked; browser popup blocker set to strict; kiosk/embedded browsers with popups disabled.

Related errors


AI-assisted analysis of benweet/stackedit@6dce2a5e36 (2026-09-01). Data as JSON: /api/errors/98742af75e1d95ca. Report an issue: GitHub.