Skip to content

fix: read account state from private REST API after OpenRouter removed Server Actions - #6

Merged
erikchi merged 1 commit into
mainfrom
erikchi/fix-server-action-removal
Aug 26, 2026
Merged

fix: read account state from private REST API after OpenRouter removed Server Actions#6
erikchi merged 1 commit into
mainfrom
erikchi/fix-server-action-removal

Conversation

@erikchi

@erikchi erikchi commented Aug 26, 2026

Copy link
Copy Markdown
Member

Symptom

All stations failing again, consecutive_failure_count: 350:

{"reason":"failed_to_fetch_activity",
 "error_detail":"no activity hash found, available: map[] (pages_ok=2 pages_signed_out=0 chunks_seen=3425 chunks_fetched=85)"}

The diagnostics added in #4 did the triage: pages_ok=2 (cookies alive), chunks_seen=3425 (bundle discovery healthy after the last fix). So the break was downstream of both — not cookies, not the bundle path.

Root cause

OpenRouter migrated their private frontend off Next.js Server Actions onto REST + React Query. getCurrentUserSA no longer exists, so there is no action hash left to find.

Ground truth from the authenticated /activity page:

  • All 79 referenced chunks fetch 200 — nothing is missing or 404ing
  • The only server actions left in the bundle are errSA, refreshSA, sealSignupCfMetadataSA
  • getCurrentUserSA is replaced by React Query hooks — useCurrentUser, currentUserOptions, currentUserKeys — whose queryFn targets:
GET /api/frontend/v1/private/users/current  →  {"data": { email, enable_training, enforce_zdr, ... }}

That single endpoint carries the email and every user-scope required toggle. The workspace-scope toggle still comes from the SSR settings page, which is unaffected.

Fix

FetchActivityData now calls the REST endpoint first, keeping the legacy server-action paths as fallbacks so an upstream revert costs us nothing. Response unwrapping is a pure parseCurrentUserResponse so the contract is unit-testable without a live session.

This also removes the verifier's dependence on scraping the minified bundle for user data — the layer that broke twice this month: first when the bundle moved to /_next/static/immutable/chunks/ (#4), now when the action it hosted was deleted. A REST contract is the more stable surface.

Verification

End-to-end against a live account:

Action hashes: map[]              ← dead machinery, untouched
Activity data fetched successfully!
Result: ok
  enable_training ... OK (false) [user]      (7/7 required toggles OK)

The empty hash map is the point: the new path succeeds without it.

Tests cover the success envelope, the real 401 No user or org id found in auth cookie body, and rejection of empty/HTML responses — the last one matters because a signed-out page must never be mistaken for a compliant account. go build ./... and go test ./... green.

⚠️ Not fixed here — new registrations still broken

CreateProvisioningKey / DeleteProvisioningKey still use the removed provisioning_keys_create / provisioning_keys_delete actions, so registration and unregister remain broken; already-registered stations verify fine. Replacement endpoint is /api/frontend/v1/private/management-keys. Left out because exercising it creates a real management key on a live account — wanted a decision before doing that.

🤖 Generated with Claude Code

… action

OpenRouter migrated their private frontend off Next.js Server Actions onto
REST + React Query. getCurrentUserSA no longer exists, so every station failed
with `no activity hash found, available: map[]` -- both periodic verification
(verification.go) and registration (handlers.go) call FetchActivityData.

Evidence from the authenticated /activity page: all 79 referenced chunks fetch
200, and the only server actions left in the bundle are errSA, refreshSA and
sealSignupCfMetadataSA. getCurrentUserSA is replaced by React Query hooks
(useCurrentUser / currentUserOptions) whose queryFn targets
GET /api/frontend/v1/private/users/current. That endpoint returns
{"data":{...}} with email and every user-scope required toggle.

FetchActivityData now tries the REST endpoint first and keeps the legacy
server-action paths as fallbacks, so a revert upstream costs us nothing.

This also removes the verifier's dependence on scraping OpenRouter's minified
bundle for the user-data path -- the layer that broke twice this month, first
when the bundle moved to /_next/static/immutable/chunks/ and now when the
action it hosted was deleted. A REST contract is the more stable surface.

Verified end-to-end against a live account: activity data fetched, Result: ok,
all 7 required toggles OK -- with `Action hashes: map[]`, proving the new path
does not touch the dead machinery.

Not covered here: CreateProvisioningKey / DeleteProvisioningKey still use the
removed provisioning-key actions, so new registrations and unregisters remain
broken. Their replacement is /api/frontend/v1/private/management-keys.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@erikchi
erikchi merged commit 2b2314f into main Aug 26, 2026
2 checks passed
@erikchi
erikchi deleted the erikchi/fix-server-action-removal branch August 26, 2026 04:42
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