musistudio/claude-code-router · error · Error

Only http and https QR login URLs can be opened.

Error message

Only http and https QR login URLs can be opened.

What it means

Thrown by parseQrWindowUrl when the URL for a bot-gateway QR login window fails the isHttpUrl check. QR windows are restricted to http/https because they render remote login pages; other schemes could execute privileged BrowserWindow behavior or load local content.

Source

Thrown at packages/electron/src/main/bot-gateway-qr-window-service.ts:91

export function closeBotGatewayQrWindow(
  request: BotGatewayQrWindowCloseRequest
): BotGatewayQrWindowCloseResult {
  const sessionId = request.sessionId.trim();
  const window = qrWindows.get(sessionId);
  if (!window || window.isDestroyed()) {
    qrWindows.delete(sessionId);
    return { closed: false };
  }
  qrWindows.delete(sessionId);
  window.close();
  return { closed: true };
}

function parseQrWindowUrl(value: string): string {
  const trimmed = value.trim();
  if (!isHttpUrl(trimmed)) {
    throw new Error("Only http and https QR login URLs can be opened.");
  }
  return new URL(trimmed).toString();
}

async function loadQrWindowUrl(window: BrowserWindow, url: string, allowClosed: boolean) {
  try {
    await window.loadURL(url);
  } catch (error) {
    if (allowClosed && window.isDestroyed()) {
      return;
    }
    throw error;
  }
}

async function waitForQrWindowClose(
  window: BrowserWindow
): Promise<Omit<BotGatewayQrWindowOpenResult, "opened">> {

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Use the full http:// or https:// URL of the bot gateway's QR login page.
  2. Check gateway configuration for a truncated or scheme-less base URL and fix it.
  3. Do not point the QR window at local files or embedded data URIs.

Example fix

// before
await openBotGatewayQrWindow({ sessionId, url: "file:///app/qr.html" });

// after
await openBotGatewayQrWindow({ sessionId, url: "https://gateway.example.com/qr" });
Defensive patterns

Strategy: validation

Validate before calling

function isHttpUrl(v: string): boolean { try { const p = new URL(v.trim()).protocol; return p === "http:" || p === "https:"; } catch { return false; } }
if (!isHttpUrl(gatewayQrUrl)) throw new Error("Gateway QR URL must be http(s)");

Type guard

function isHttpUrl(value: string): value is `http${"s" | ""}://${string}` { try { const p = new URL(value.trim()).protocol; return p === "http:" || p === "https:"; } catch { return false; } }

Try / catch

try { await openBotGatewayQrWindow({ sessionId, url }); } catch (e) { if (e instanceof Error && e.message.includes("Only http and https QR login URLs")) { /* fix gateway URL config */ } throw e; }

Prevention

When it happens

Trigger: Calling openBotGatewayQrWindow with a url that is not http(s): e.g. 'file:///qr.html', 'about:blank', 'data:text/html,...', or a URL string the isHttpUrl helper rejects (missing protocol, chrome:// scheme).

Common situations: Passing a local asset path or a data: URI instead of the gateway's HTTP endpoint; the gateway URL was misconfigured or truncated so the protocol is missing.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/849c3454abf5612a. Report an issue: GitHub.