Hmbown/CodeWhale · error

Enter a Runtime token to connect once

Error message

Enter a Runtime token to connect once

What it means

connectMobileSession requires a Runtime bearer token to authenticate the one-time POST to /__codewhale/mobile/session. The token() accessor returning an empty value means the user has not entered a token, so the runtime throws before making any network request.

Solutions

  1. Enter a Runtime token in the mobile UI's token field before connecting.
  2. Ensure the token input's value is wired to the token() accessor correctly.
  3. If the token should be pre-provisioned, populate it into the field/storage before calling connectMobileSession.

Example fix

// before
await connectMobileSession();
// after
if (!tokenInput.value.trim()) { showHint('Enter a Runtime token first'); return; }
await connectMobileSession();
Defensive patterns

Strategy: validation

Validate before calling

const runtimeToken = tokenInput.value.trim();
if (!runtimeToken) { showHint('Enter a Runtime token first'); return; }

Type guard

function hasToken(t) { return typeof t === 'string' && t.trim().length > 0; }

Try / catch

try {
  await connectMobileSession();
} catch (e) {
  if (String(e.message).includes('token')) focusTokenInput();
}

Prevention

When it happens

Trigger: Tapping connect without typing a Runtime token into the token input; the token field was cleared or never populated on page load.

Common situations: First-time setup where the user skips the token field; token lost after localStorage/session clear; UI event firing before the user finished entering the token.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/6ef488c90e9cd371. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_mobile.html:375

        credentials: "same-origin",
        headers: headers(options.headers || {})
      }));
      if (!res.ok) {
        if (res.status === 401) clearMobileSession();
        let detail = await res.text();
        try {
          const parsed = JSON.parse(detail);
          detail = parsed.error?.message || detail;
        } catch (_) {}
        throw new Error(detail || ("HTTP " + res.status));
      }
      if (res.status === 204) return null;
      return res.json();
    }

    async function connectMobileSession() {
      const runtimeToken = token();
      if (!runtimeToken) throw new Error("Enter a Runtime token to connect once");
      let res;
      try {
        res = await fetch("/__codewhale/mobile/session", {
          method: "POST",
          credentials: "same-origin",
          headers: { "Authorization": "Bearer " + runtimeToken }
        });
      } finally {
        $("token").value = "";
      }
      if (!res.ok) {
        let detail = await res.text();
        try {
          const parsed = JSON.parse(detail);
          detail = parsed.error?.message || detail;
        } catch (_) {}
        throw new Error(detail || ("HTTP " + res.status));
      }

View on GitHub (pinned to 73e0f67d83)