can1357/oh-my-pi · error · Error

Smithery login session expired. Please try again.

Error message

Smithery login session expired. Please try again.

What it means

Thrown by pollSmitheryCliAuthSession when the poll endpoint answers 404 or 410, meaning the CLI login session no longer exists on the server — it expired or was consumed. The user must restart the login flow from scratch; retrying the poll will keep failing.

Source

Thrown at packages/coding-agent/src/mcp/smithery-auth.ts:61

		method: "POST",
		signal: withTimeoutSignal(SMITHERY_AUTH_TIMEOUT_MS),
	});
	if (!response.ok) {
		throw new Error(`Failed to create Smithery auth session: ${response.status} ${response.statusText}`);
	}
	return (await response.json()) as SmitheryCliAuthSession;
}

export async function pollSmitheryCliAuthSession(
	sessionId: string,
	signal?: AbortSignal,
): Promise<SmitheryCliPollResponse> {
	const response = await fetch(`${SMITHERY_URL}/api/auth/cli/poll/${sessionId}`, {
		signal: withTimeoutSignal(SMITHERY_POLL_TIMEOUT_MS, signal),
	});
	if (!response.ok) {
		if (response.status === 404 || response.status === 410) {
			throw new Error("Smithery login session expired. Please try again.");
		}
		throw new Error(`Smithery auth polling failed: ${response.status} ${response.statusText}`);
	}
	return (await response.json()) as SmitheryCliPollResponse;
}

export async function getSmitheryApiKey(): Promise<string | undefined> {
	const envKey = normalizeApiKey(process.env.SMITHERY_API_KEY);
	if (envKey) return envKey;

	const authPath = getSmitheryAuthPath();
	try {
		const payload = (await Bun.file(authPath).json()) as SmitheryAuthPayload;
		return normalizeApiKey(payload.apiKey);
	} catch (error) {
		if (isEnoent(error)) return undefined;
		logger.warn("Failed to read Smithery auth file, treating as missing", { path: authPath, error });
		return undefined;

View on GitHub (pinned to 9690622007)

Solutions

  1. Restart the Smithery login command to get a fresh session and complete the browser step promptly
  2. Complete the browser approval quickly after starting login — sessions are short-lived
  3. Avoid suspending/sleeping the machine during the login flow
  4. If it keeps happening immediately, check clock skew (system clock far off can invalidate sessions)

Example fix

// before: retrying the same expired session
await pollSmitheryCliAuthSession(sessionId); // keeps throwing
// after: start a new session on expiry
try {
  await pollSmitheryCliAuthSession(sessionId);
} catch (e) {
  if (String(e.message).includes("expired")) await restartSmitheryLogin();
  else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// track session age and abandon before polling an obviously expired session
const sessionAge = Date.now() - session.createdAt;
if (sessionAge > SESSION_TTL_MS) {
  session = await createSmitheryCliAuthSession(); // fresh session instead of stale poll
}

Type guard

function isSessionExpired(err: unknown): boolean {
  return err instanceof Error && err.message.includes("Smithery login session expired");
}

Try / catch

try {
  const res = await pollSmitheryCliAuthSession(sessionId, signal);
} catch (err) {
  if (isSessionExpired(err)) {
    sessionId = (await createSmitheryCliAuthSession()).sessionId; // restart login
  } else throw err;
}

Prevention

When it happens

Trigger: Polling a Smithery CLI auth session whose sessionId the server no longer recognizes: session TTL elapsed before the user completed browser login, or the session was already finalized.

Common situations: User took too long to approve the login in the browser (past the session TTL), user completed login in a different window and the session was consumed, machine slept during the login wait.

Related errors


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