RocketChat/Rocket.Chat · error · Error
Could not open popup
Error message
Could not open popup
What it means
Thrown by the CAS login popup helper when window.open() returns null. Browsers return null from window.open when a popup blocker prevents the new window from being created. This function orchestrates the CAS (Central Authentication Service) single sign-on flow by opening a centered popup window for the CAS login URL.
Source
Thrown at apps/meteor/client/lib/openCASLoginPopup.ts:20
import { getRootUrlPathPrefix } from './meteorRuntimeConfig';
import { settings } from './settings';
const openCenteredPopup = (url: string, width: number, height: number) => {
const screenX = window.screenX ?? window.screenLeft;
const screenY = window.screenY ?? window.screenTop;
const outerWidth = window.outerWidth ?? document.body.clientWidth;
const outerHeight = window.outerHeight ?? document.body.clientHeight - 22;
// XXX what is the 22? Probably the height of the title bar.
// Use `outerWidth - width` and `outerHeight - height` for help in
// positioning the popup centered relative to the current window
const left = screenX + (outerWidth - width) / 2;
const top = screenY + (outerHeight - height) / 2;
const features = `width=${width},height=${height},left=${left},top=${top},scrollbars=yes`;
const newwindow = window.open(url, 'Login', features);
if (!newwindow) {
throw new Error('Could not open popup');
}
newwindow.focus();
return newwindow;
};
const getPopupUrl = (credentialToken: string): string => {
const loginUrl = settings.peek<string | undefined>('CAS_login_url');
if (!loginUrl) {
throw new Error('CAS_login_url not set');
}
const appUrl = absoluteUrl().replace(/\/$/, '') + getRootUrlPathPrefix();
const serviceUrl = `${appUrl}/_cas/${credentialToken}`;
const url = new URL(loginUrl);
url.searchParams.set('service', serviceUrl);View on GitHub (pinned to f9d3ec372b)
Solutions
- Ensure window.open is called synchronously within a user-initiated event handler (click, tap).
- Prompt the user to disable popup blocking for this site if the popup fails to open.
- Catch the error and show a fallback message with a direct link the user can click manually.
- Use a redirect-based CAS flow instead of a popup if popups are consistently blocked.
Example fix
// before
const popup = openCASLoginPopup(token); // may be outside click handler
// after
// In a click handler:
button.onclick = () => {
try {
const popup = openCASLoginPopup(token);
} catch {
showPopupBlockedMessage();
}
}; Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof window === 'undefined' || !window.open) {
throw new Error('Popups not supported in this environment');
}
// ensure called within a user gesture
const popup = openCASLoginPopup(token); Type guard
const canOpenPopup = (): boolean => typeof window !== 'undefined' && typeof window.open === 'function';
Try / catch
try {
const popup = openCASLoginPopup(token);
} catch (e) {
if (e instanceof Error && e.message === 'Could not open popup') {
showPopupBlockedGuidance();
return;
}
throw e;
} Prevention
- Always call openCASLoginPopup from within a synchronous user gesture handler (click/tap).
- Inform users to allow popups for the Rocket.Chat domain.
- Provide a redirect-based fallback when popup blocking is detected.
- Test in browsers with default popup blocker settings.
When it happens
Trigger: The browser's built-in popup blocker is enabled and blocks the window.open call. A browser extension (ad blocker, privacy extension) blocks popups. window.open is called outside a direct user gesture (some browsers block programmatic popups not triggered by user clicks). Corporate browser policy disables popups.
Common situations: User has a popup blocker extension installed. The CAS login is triggered programmatically (e.g., on page load or via a timer) instead of from a click handler. Chrome/Firefox/Safari popup blocker settings are at their default (which blocks non-user-initiated popups). Enterprise managed browsers with strict popup policies.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/f3a357d2157716e4.
Report an issue: GitHub.