Skip to content

fix(auth): stop gated HuggingFace models bouncing users to /login - #88

Merged
jicowan merged 1 commit into
mainfrom
feature/gated-model-login-redirect
Jul 7, 2026
Merged

fix(auth): stop gated HuggingFace models bouncing users to /login#88
jicowan merged 1 commit into
mainfrom
feature/gated-model-login-redirect

Conversation

@jicowan

@jicowan jicowan commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Problem

A user reported being redirected to /login when selecting a model from the MODEL (HUGGINGFACE ID) dropdown on the New Benchmark page — while switching between several models. It only reproduced when auth is disabled.

Root cause

Selecting a model fires GET /recommend, /memory-breakdown, and (on the Estimate page) /estimate. Each fetches the model config from HuggingFace. For a gated model — or a missing/expired platform HF token, or HF rate-limiting — HuggingFace returns 401, and the handlers relayed that status verbatim. The frontend's fetchJSON treats any 401 as a session expiry: it tries a silent /auth/refresh and, on failure, redirects to /login.

Why auth-disabled-only: with auth enabled the silent refresh succeeds and the retried 401 falls through to the normal error path (no redirect). With auth disabled, /auth/refresh returns 503, so the refresh always fails and the redirect fires every time. The middleware had already injected a synthetic admin, so it was never a real auth failure.

Fix (two layers)

  • Backend — new writeHFError helper remaps a HuggingFace 401/403 to 422 Unprocessable Entity (preserving the actionable "model is gated — provide an HF token" message); non-HFError failures become 502. Wired into handleRecommend, handleMemoryBreakdown, and handleEstimate.
  • Frontend — the auth middleware now sets WWW-Authenticate: Bearer on genuine auth 401s; fetchJSON runs its refresh + redirect flow only when that marker is present. This protects every current and future endpoint from the same misclassification.

Audit

Full sweep of gated-model entry points. The bug surface is exactly the three fetchJSON endpoints that fetch HF config, reached from Run.tsx (recommend + memory-breakdown) and Estimate.tsx (estimate). Everywhere else is safe: ModelCombobox hits HuggingFace directly via raw fetch (not wrapped by fetchJSON) and already shows an inline gated warning; ModelCache and the create-run POSTs don't fetch HF config.

Tests

  • go test ./... ✅ · go vet ./... ✅ — new regression tests: gated 401/403 → 422 across all three endpoints with auth disabled, generic HF error → 502, WWW-Authenticate present on auth 401.
  • npx tsc --noEmit ✅ · npm run build ✅ · npm test ✅ (21 tests).

Deploy note

Touches both backend and frontend, so both accelbench-api and accelbench-web need to be rebuilt/pushed and rolled.

🤖 Generated with Claude Code

Selecting a gated model on the New Benchmark or Estimate page could
redirect the user to /login. The model-config endpoints (/recommend,
/estimate, /memory-breakdown) fetch config from HuggingFace, which
returns 401 for gated models (or a missing/expired platform token, or
rate-limiting). The handlers relayed that 401 verbatim, and the
frontend's fetchJSON treats any 401 as an expired session.

The symptom only showed with auth disabled: with auth enabled the
silent /auth/refresh succeeds and the retried 401 falls through to the
normal error path, but with auth disabled /auth/refresh returns 503, so
the refresh always fails and the redirect fires every time.

Fix, both layers:
- Backend: new writeHFError helper remaps an HF 401/403 to 422 so it
  never collides with the app's own auth 401, preserving the "model is
  gated — provide an HF token" message. Wired into handleRecommend,
  handleMemoryBreakdown, and handleEstimate.
- Frontend: the auth middleware now sets WWW-Authenticate on genuine
  auth 401s; fetchJSON only runs its refresh + redirect flow when that
  marker is present, protecting every current and future endpoint from
  the same misclassification.

Adds regression tests: gated 401/403 -> 422 across all three endpoints
with auth disabled, generic HF error -> 502, and WWW-Authenticate
presence on auth 401s.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jicowan
jicowan merged commit b6ed65f into main Jul 7, 2026
6 of 7 checks passed
@jicowan
jicowan deleted the feature/gated-model-login-redirect branch July 7, 2026 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant