can1357/oh-my-pi · error · Error

Smithery authorization timed out after 5 minutes.

Error message

Smithery authorization timed out after 5 minutes.

What it means

Thrown by #waitForSmitheryCliApiKey when the browser-based Smithery CLI authorization polling loop exceeds its 5-minute deadline (300s timeout, 2s poll interval) without the session reaching a success or error status. The user was asked to authorize OMP in the browser, but approval never arrived in time, so the controller gives up with a timeout.

Source

Thrown at packages/coding-agent/src/modes/controllers/mcp-command-controller.ts:2408

		}
	}

	async #handleSmitheryLoginWithApiKey(): Promise<boolean> {
		const apiKey = await this.#promptSmitheryApiKey("Smithery API key (Esc to cancel)");
		if (!apiKey) return false;
		await saveSmitheryApiKey(apiKey);
		this.ctx.showStatus("Smithery API key saved.");
		return true;
	}

	async #waitForSmitheryCliApiKey(sessionId: string, signal: AbortSignal): Promise<string> {
		const pollIntervalMs = 2_000;
		const timeoutMs = 300_000;
		const startedAt = Date.now();

		while (!signal.aborted) {
			if (Date.now() - startedAt >= timeoutMs) {
				throw new Error("Smithery authorization timed out after 5 minutes.");
			}
			let response: SmitheryCliPollResponse;
			try {
				response = await pollSmitheryCliAuthSession(sessionId, signal);
			} catch (error) {
				// A single hung/slow poll aborts with TimeoutError; retry until the deadline.
				if (isTimeoutError(error)) continue;
				throw error;
			}
			if (response.status === "success" && response.apiKey) {
				return response.apiKey;
			}
			if (response.status === "error") {
				throw new Error(response.message ?? "Smithery authorization failed.");
			}
			await Bun.sleep(pollIntervalMs);
		}

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-run /mcp smithery-login and complete the browser authorization promptly (within 5 minutes).
  2. If the browser does not open, copy the 'Authorize URL' shown in the message panel and open it manually.
  3. Skip the browser flow entirely: run /mcp smithery-login and paste your Smithery API key instead (the controller falls back to key input when browser auth fails).
  4. Check Smithery's status — if their auth service is degraded, sessions may never transition to success; retry later.
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the authorize URL is reachable before starting the browser flow
const r = await fetch(session.authUrl, { redirect: "manual" });
if (r.type === "error" && !(r.status || r.status === 0)) throw new Error("Authorize URL unreachable — fix browser/network before login");

Type guard

function isSmitheryAuthTimeout(err: unknown): err is Error {
  return err instanceof Error && err.message.startsWith("Smithery authorization timed out");
}

Try / catch

try {
  await smitheryLogin();
} catch (err) {
  if (isSmitheryAuthTimeout(err)) {
    // retry once; if it times out again, fall back to pasting an API key
    return await smitheryApiKeyFallback();
  }
  throw err;
}

Prevention

When it happens

Trigger: Running /mcp smithery-login (browser flow) and not completing the browser authorization within 5 minutes — or the poll loop running while the signal never aborts but the session stays 'pending' past the deadline.

Common situations: The browser tab was never opened (popup blocked, no browser on a headless box); the user missed the notification; Smithery's login page hung or the session never advanced server-side; the user walked away and came back after the deadline.

Understand the failure class

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/4dfbbd50250206e5. Report an issue: GitHub.