usestrix/strix · error · CodexAuthError

not_authenticated

not_authenticated

Error message

not_authenticated: not signed in; run: strix auth login

What it means

CodexAuthError with code `not_authenticated` raised by `get_valid_token()` when `read_record()` returns None — the auth store at ~/.strix/subscription-auth.json has no valid Codex OAuth record (missing file, non-oauth record type, or record missing access/refresh/account_id fields). The message tells the user the exact remedy: run `strix auth login`.

Source

Thrown at strix/config/codex.py:330

        org_id = organizations[0].get("id")
        if isinstance(org_id, str) and org_id:
            return org_id
    return None


def _near_expiry(record: dict[str, Any]) -> bool:
    expires_at = record.get("expires_at")
    if not isinstance(expires_at, int | float):
        return True
    return expires_at - _EXPIRY_SKEW_S <= time.time()


def get_valid_token() -> tuple[str, str]:
    """Return ``(access_token, account_id)``, refreshing under the cross-process
    guard if near expiry."""
    record = read_record()
    if record is None:
        raise CodexAuthError("not_authenticated", "not signed in; run: strix auth login")
    if not _near_expiry(record):
        return record["access"], record["account_id"]
    with _refresh_guard():
        record = read_record()
        if record is None:
            raise CodexAuthError("not_authenticated", "not signed in; run: strix auth login")
        if not _near_expiry(record):
            return record["access"], record["account_id"]
        try:
            refreshed = refresh_tokens(record["refresh"])
        except CodexAuthError:
            # A peer process may have already spent this single-use refresh token.
            latest = read_record()
            if latest and latest["refresh"] != record["refresh"] and not _near_expiry(latest):
                return latest["access"], latest["account_id"]
            raise
        save_record(refreshed)
        return refreshed["access"], refreshed["account_id"]

View on GitHub (pinned to 8551339130)

Solutions

  1. Run `strix auth login` and complete the browser OAuth flow on localhost:1455/auth/callback
  2. Verify state with `strix auth status` (or check that ~/.strix/subscription-auth.json exists and has type=oauth with access/refresh/account_id)
  3. If the file is corrupted, `strix auth logout` then login again to rewrite it cleanly
  4. If you don't intend to use ChatGPT subscription auth, switch the model config to an API-key provider (set the appropriate API key env var)

Example fix

# before
strix -n -t ./ --scan-mode quick   # raises not_authenticated when provider is codex
# after
strix auth login
strix -n -t ./ --scan-mode quick
Defensive patterns

Strategy: validation

Validate before calling

from strix.config.codex import is_authenticated

if not is_authenticated():
    raise SystemExit("Not signed in for Codex auth. Run: strix auth login")
# safe to proceed
access, account = get_valid_token()

Try / catch

from strix.config.codex import CodexAuthError, get_valid_token

try:
    access, account = get_valid_token()
except CodexAuthError as e:
    if e.code == "not_authenticated":
        raise SystemExit("Run `strix auth login` and retry") from e
    raise

Prevention

When it happens

Trigger: Any operation that needs a Codex token (starting a scan configured for the ChatGPT/Codex provider) before authentication, after `strix auth logout`, after the auth file is deleted/corrupted, or when the selected provider is codex but login was done for a different provider.

Common situations: Fresh installs where the user configured STRIX_LLM for codex without logging in; auth file removed by cleanup tools or another machine's dotfiles sync; JSON corrupted (read_record's _read_store returns {} on parse failure); user logged out in one terminal and started a scan in another.

Understand the failure class

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/d7cc9f586b488095. Report an issue: GitHub.