Hmbown/CodeWhale · error · Error

This browser session is not authenticated. Restart `codewhal

Error message

This browser session is not authenticated. Restart `codewhale web` to open a fresh one-time session.

What it means

The app.mjs request wrapper special-cases 401: any 401 from the runtime API is reported as an unauthenticated browser session. `codewhale web` authenticates the browser via a one-time session; when that session no longer exists server-side (restart, expiry), every API call returns 401.

Source

Thrown at crates/tui/src/runtime_web/app.mjs:712

    if (options.body != null && !headers.has("content-type")) {
      headers.set("content-type", "application/json");
    }
    const response = await fetch(path, {
      ...options,
      headers,
      credentials: "same-origin",
      cache: "no-store",
    });
    if (!response.ok) {
      let message = `${response.status} ${response.statusText}`.trim();
      try {
        const body = await response.json();
        message = body?.error?.message || body?.message || message;
      } catch (_error) {
        // The status line is enough when the response is not JSON.
      }
      if (response.status === 401) {
        message = "This browser session is not authenticated. Restart `codewhale web` to open a fresh one-time session.";
      }
      throw new Error(message);
    }
    if (response.status === 204) return null;
    const contentType = response.headers.get("content-type") || "";
    return contentType.includes("application/json") ? response.json() : response.text();
  }

  function renderThreadList() {
    dom.threadList.replaceChildren();
    if (app.summaries.length === 0) {
      const empty = element("p", "thread-preview", "No matching threads");
      empty.style.padding = "8px 10px";
      dom.threadList.append(empty);
      return;
    }
    for (const summary of app.summaries) {
      const row = element("button", "thread-row");

View on GitHub (pinned to 8880682c63)

Solutions

  1. Restart `codewhale web` to mint a fresh one-time session and open the URL it prints
  2. Close stale tabs from the old session
  3. Allow cookies for the runtime origin
Defensive patterns

Strategy: fallback

Validate before calling

const res = await fetch('/v1/session', { credentials: 'same-origin' });
if (res.status === 401) {
  showReauthNotice('Restart `codewhale web` to open a fresh one-time session.');
  return;
}

Try / catch

catch (err) {
  if (err.message.includes('not authenticated')) {
    stopPolling();
    showReauthNotice(err.message);
    return null;
  }
  throw err;
}

Prevention

When it happens

Trigger: The web runtime restarted (session store reset) while the tab stayed open; the session cookie was cleared or blocked; the one-time URL opened after expiry; same-origin credentialed requests sent from a different origin.

Common situations: Leaving the web UI open overnight; running `codewhale web` twice so the second instance invalidates the first session; privacy settings dropping cookies.

Understand the failure class

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/b5c2881c8e23e59c. Report an issue: GitHub.