fix: read account state from private REST API after OpenRouter removed Server Actions - #6
Merged
Merged
Conversation
… 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
getCurrentUserSAno longer exists, so there is no action hash left to find.Ground truth from the authenticated
/activitypage:200— nothing is missing or 404ingerrSA,refreshSA,sealSignupCfMetadataSAgetCurrentUserSAis replaced by React Query hooks —useCurrentUser,currentUserOptions,currentUserKeys— whosequeryFntargets: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
FetchActivityDatanow calls the REST endpoint first, keeping the legacy server-action paths as fallbacks so an upstream revert costs us nothing. Response unwrapping is a pureparseCurrentUserResponseso 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:
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 cookiebody, 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 ./...andgo test ./...green.CreateProvisioningKey/DeleteProvisioningKeystill use the removedprovisioning_keys_create/provisioning_keys_deleteactions, 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