Skip to content

fix(provider-grok): recheck Grok login once after a logged-out probe - #20358

Merged
juliusmarminge merged 7 commits into
pingdotgg:mainfrom
only21mil:fix/14285-grok-expired-token-health
Oct 20, 2026
Merged

juliusmarminge merged 7 commits into
pingdotgg:mainfrom
only21mil:fix/14285-grok-expired-token-health

Conversation

@only21mil

@only21mil only21mil commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Problem

When a Grok access token has expired but its refresh token is still valid, grok models prints "You are not authenticated.", refreshes the token in the same process, and exits 0 without a login line. T3 Code read that first banner as the verdict, so a signed-in user saw "Grok is unauthenticated" and the picker hid Grok until providers were refreshed by hand. Fixes #14285.

Change

checkGrokProviderStatus runs grok models once more when the first clean run parses as logged out and XAI_API_KEY is unset. The second run starts only after the first process has exited, so it never contends with the CLI's own auth lock. Its verdict replaces the first one only when it carries a login line; a timeout, failed exit, or unparseable output keeps the first result, so a real logout still reports unauthenticated. Logged-in and API-key users run the command once as before.

The probe body moved into a module-level probeGrokModels helper so it can run twice without duplicating the parsing or the failure log.

Tests

One regression in apps/server/src/provider/GrokProvider.test.ts: the fake CLI prints the logged-out banner on the first models call and the logged-in banner on the second, and the probe must report ready / authenticated. It fails on main (expected 'error' to be 'ready') and passes here. The existing logged-out fixture repeats the same output on the recheck and still proves a real logout stays unauthenticated, so no further test was added.

Verification

Headless Linux, Node 24. checkGrokProviderStatus run against a stub grok binary with XAI_API_KEY unset. "refresh" prints logged out on the first models call and logged in afterwards; "logged-out" always prints logged out. ACP initialize is not stubbed, hence the warning status on the authenticated row.

stub main this PR
refresh error / unauthenticated, 1 grok models call warning / authenticated, 2 calls
logged-out error / unauthenticated, 1 call error / unauthenticated, 2 calls
  • vp test run src/provider/GrokProvider.test.ts (apps/server): 34 passed.
  • vp test run in packages/provider-grok: 119 passed, 4 skipped.
  • Targeted vp lint, vp fmt --check, and provider-grok typecheck: clean.
  • Not verified here: a real Grok account with an expired token, macOS, Windows, iOS, Android, and Electron desktop. The server-side verdict is the only thing that changed, so the banner and picker follow it.

Independent read-only reviews by Claude Opus 5.5 and GPT-6-Sol found no blockers.

Takes over #20358 by @only21mil, whose diagnosis and regression test this keeps. Implementation: Claude Fable 5.1 through Claude Code in T3 Code.

only21mil and others added 3 commits October 15, 2026 20:44
Co-authored-by: Abdurahmon <89484240+abdurahmon27@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An expired access token makes `grok models` print "You are not authenticated." before the CLI refreshes the token in the same run, so the health check reported a signed-in user as logged out. Run `grok models` once more after the first process exits when it reports logged out, and use that verdict. A real logout stays unauthenticated.

Builds on the approach in pingdotgg#14731.

Fixes pingdotgg#14285

Co-authored-by: Abdurahmon <89484240+abdurahmon27@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 16, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR changes production Grok authentication detection, including when a provider transitions from unauthenticated to authenticated after a token refresh. Although the implementation is narrowly scoped and tested, authentication-related runtime changes require human review.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8b15e496-e166-4086-b4d0-a2c7b61b7786
📥 Commits

Reviewing files that changed from the base of the PR and between 7abd1ae and b73e732.

📒 Files selected for processing: 1
  • packages/provider-grok/src/server/status.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

📝 Walkthrough

The Grok status check now isolates CLI probing and retries an unauthenticated result when no API key is configured. Tests simulate sequential CLI responses and verify an authenticated, ready provider snapshot.

Changes: Grok authentication status

Layer / File(s) Summary
Retry the authentication probe
packages/provider-grok/src/server/status.ts
probeGrokModels parses output only after a successful command and records failure categories. The status check trims XAI_API_KEY once and retries an unauthenticated result when no key is configured.
Test sequential probe results
apps/server/src/provider/GrokProvider.test.ts
The fake CLI accepts sequential models outputs and repeats the final output for later calls. A test verifies that an authenticated retry produces a ready, authenticated snapshot.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant ProviderStatus as Grok provider status check
  participant GrokCLI as grok models CLI
  participant ProviderSnapshot as provider snapshot
  ProviderStatus->>GrokCLI: Run initial probe
  GrokCLI-->>ProviderStatus: Return unauthenticated result
  ProviderStatus->>GrokCLI: Retry when no API key is set
  GrokCLI-->>ProviderStatus: Return authenticated result
  ProviderStatus->>ProviderSnapshot: Produce ready, authenticated snapshot
Loading

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to b73e7

The Grok status retry has no identified merge-blocking issue; proceed with normal checks.

Architecture Summary

Architecture risk: 🔵 Low · up to b73e7

The change affects 2 systems.

Changed systems: packages/provider-grok, apps/server

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/provider-grok (library) was modified; 1 changed file maps to changed impact.
  • observed — apps/server (service) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/server/src/provider/GrokProvider.test.ts: The local fake-CLI helper’s modelsOutput input now accepts a string or a readonly array of strings instead of only a string.
  • observed — Modified behavior in apps/server/src/provider/GrokProvider.test.ts: The mock CLI now counts models calls and serves the corresponding configured output, clamping later calls to the last output; previously, every call printed the same single output.
  • observed — Modified behavior in apps/server/src/provider/GrokProvider.test.ts: Adds a status test in which grok models first reports logged out and then logged in; it expects the resulting snapshot to be ready and authenticated.
  • observed — Modified behavior in packages/provider-grok/src/server/status.ts: Added probeGrokModels, which runs grok models with the authentication timeout, parses only successful exit output, returns an unknown-authentication/empty-model result for failures or timeouts, and logs the failure category.
Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: retrying the Grok login check after an initial logged-out result.
Description check Passed The description covers the problem, implementation, regression tests, verification results, limitations, and linked issue. The scope and approval context is supported by the linked bug and focused-fix…
Linked Issues check Passed Issue [#14285] requires one retry after a clean unauthenticated grok models result when XAI_API_KEY is unset. checkGrokProviderStatus uses the module-level probeGrokModels helper, waits for th…
Out of Scope Changes check Passed The changes are limited to the Grok status probe and its regression-test CLI helper. The helper extraction supports the required retry without changing public entities. The test sequence directly mode…
Full details: Description check

Explanation

The description covers the problem, implementation, regression tests, verification results, limitations, and linked issue. The scope and approval context is supported by the linked bug and focused-fix explanation, although no separate heading is provided.

Full details: Linked Issues check

Explanation

Issue [#14285] requires one retry after a clean unauthenticated grok models result when XAI_API_KEY is unset. checkGrokProviderStatus uses the module-level probeGrokModels helper, waits for the first process to exit, and accepts the retry only when it provides a login verdict. Failed, timed-out, or unparseable retries retain the first result. The regression test covers refreshed authentication, and existing coverage preserves genuine logout behavior.

Full details: Out of Scope Changes check

Explanation

The changes are limited to the Grok status probe and its regression-test CLI helper. The helper extraction supports the required retry without changing public entities. The test sequence directly models the linked issue. No unrelated product behavior is demonstrated.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge juliusmarminge self-assigned this Oct 19, 2026
@juliusmarminge

Copy link
Copy Markdown
Member

Taking over this one. I'll trim the tests to the useful coverage, rebuild the implementation against current main, run independent reviews, and verify it before pushing to this branch.

juliusmarminge and others added 2 commits October 19, 2026 01:30
@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Oct 19, 2026
@juliusmarminge
juliusmarminge merged commit a2157ec into pingdotgg:main Oct 20, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Grok health check treats an expired access token as logged out

2 participants