Fix hydration 404s, Sentry deploy sync, and four open issues - #376
Conversation
Use notFound() instead of embedding the client NotFound page (fixes React #329 on /profile, /calendar, /checkpoints). Reserve profile/privacy/terms vanity slugs. Sync SENTRY_RELEASE with APP_VERSION and auto-resolve Fixes issues post-deploy. Cap parallel /instance guardian fetches; skip extension and ApiKeyError noise. Fixes WEBSITE-4, WEBSITE-19, WEBSITE-30, WEBSITE-Z Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| return true | ||
| } | ||
| if (claimed.size >= MAX_CONCURRENT_INSTANCE_FETCHES) { | ||
| return false | ||
| } | ||
| setClaimed(prev => new Set(prev).add(instanceId)) | ||
| bump() | ||
| return true | ||
| }, | ||
| [bump, claimed] | ||
| ) |
There was a problem hiding this comment.
Bug: The tryClaim function in useCallback captures a stale claimed state, causing the MAX_CONCURRENT_INSTANCE_FETCHES limit to be bypassed when multiple components claim a fetch budget simultaneously.
Severity: MEDIUM
Suggested Fix
The stale closure issue can be resolved by storing the claimed set in a useRef instead of useState. This ensures that tryClaim always reads the most current value, as refs are mutable and not captured by closures in the same way state is. Alternatively, restructure the claiming logic to avoid reading the state from outside a functional updater.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: src/components/profile/raids/history/ClusterGuardianFetchBudget.tsx#L32-L45
Potential issue: The `tryClaim` function, defined within a `useCallback`, closes over
the `claimed` state variable. When multiple `ClusterGuardians` components become visible
at once, their effects run in the same React batch. Each effect calls `tryClaim`, but
they all read the same stale snapshot of the `claimed` set. This allows the
`claimed.size >= MAX_CONCURRENT_INSTANCE_FETCHES` check to incorrectly pass for multiple
callers, leading to more than the intended maximum of 3 parallel `/instance` fetches
being dispatched. This defeats the purpose of the fetch budget mechanism.
Did we get this right? 👍 / 👎 to inform future reviews.
Co-authored-by: Cursor <cursoragent@cursor.com>
| }) => { | ||
| const containerRef = useRef<HTMLDivElement>(null) | ||
| const isVisible = useIsVisible(containerRef, { rootMargin: "240px" }) | ||
| const isVisible = useIsVisible(containerRef, { rootMargin: "0px", threshold: 0.35 }) |
There was a problem hiding this comment.
Bug: An inline object passed to the useIsVisible hook in ClusterGuardians causes a new IntersectionObserver to be created on every render, leading to performance issues.
Severity: MEDIUM
Suggested Fix
To prevent unnecessary re-creations of the IntersectionObserver, the options object should be memoized. Either define the object as a constant outside the component or wrap it with the useMemo hook to ensure its reference remains stable across renders.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: src/components/profile/raids/history/ClusterGuardians.tsx#L21
Potential issue: In the `ClusterGuardians` component, the `useIsVisible` hook is called
with an inline object literal for its `options` parameter. Because this object is a
dependency of a `useEffect` within the hook, a new `IntersectionObserver` is created on
every render of the component. While React 18's state batching prevents an infinite
loop, this pattern is a performance anti-pattern that causes unnecessary work, creating
and tearing down observers repeatedly. This leads to performance degradation, especially
if many of these components are rendered.
Summary
notFound()instead of rendering client<NotFound />on reserved paths; add bare/profilepage; reserveprofile/privacy/termsvanity slugs/instanceguardian fetches (max 3) and tighten viewport intersection on history clusterssendMessagenoise; treatApiKeyErroras handled and disable Sentry capture on/statusprobeSENTRY_RELEASEwithAPP_VERSIONon prod deploy; post-deploysync-sentry-release.shresolvesFixes WEBSITE-*issues in the correct release (usesSENTRY_ISSUE_AUTH_TOKEN)Issues addressed
WEBSITE-4, WEBSITE-19, WEBSITE-30, WEBSITE-Z
Test plan
bun scripts/check-vanity-slugs.mjsbunx tsc --noEmitbun run lintcurl -I https://raidhub.io/profile//calendar//checkpointsreturn 404APP_VERSIONreleaseMade with Cursor