🐛 Fix infinite goto loop on library list pages (media/games/books/music) - #182
Merged
Merged
Conversation
LibraryBrowser's URL-sync $effect called goto() with page.url.pathname read as a fallback when there's no query string to write. Svelte tracks every reactive read that happens during an effect's execution, including ones inside a called function — so page.url.pathname was a tracked dependency of this effect too, not just the six filter/sort fields it's meant to react to. goto() updates page.url, which made the effect see its own output as a fresh change and re-fire itself, forever: every visit to /app/media, /app/games, /app/books or /app/music hung the tab in an unrecoverable navigation-throttling loop (a reload doesn't help — the loop starts again on load). Fixed by reading page.url.pathname via untrack(), the same idiom already used in (auth)/+layout.svelte for an analogous "read this without depending on it" need. Reproduced and bisected locally: the bug is present on fefe056 (the last main commit before yesterday's gamification merges) with no gamification code involved at all — pre-existing, unrelated to any of that work, just surfaced by this deploy's timing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
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.
Summary
Urgent hotfix. Every visit to
/app/media,/app/games,/app/booksor/app/musichangs the tab in an unrecoverable browser-level navigation-throttling loop (Chrome logs "Throttling navigation to prevent the browser from hanging"). A reload doesn't help — the loop restarts on load. This is what took the site down and prompted putting it into maintenance.Root cause, confirmed by bisection — not related to the gamification work merged yesterday.
LibraryBrowser.svelte's URL-sync$effectcallsgoto()withpage.url.pathnameread as a fallback when there's no query string to write. Svelte tracks every reactive read that happens during an effect's synchronous execution, including ones inside a called function — sopage.url.pathnamewas a tracked dependency of this effect too, not just the six filter/sort fields it's meant to react to.goto()updatespage.url, which made the effect see its own output as a fresh dependency change and re-fire itself, forever.I reproduced this locally on
fefe056(the last commit onmainbefore the gamification PRs) with zero gamification code involved — the bug is pre-existing, on the sharedLibraryBrowsercomponent (last touched in #176, well before any of this week's work), just surfaced by this deploy's timing.Fix
Read
page.url.pathnameviauntrack()— the exact idiom already used in(auth)/+layout.sveltefor the same "read this value without depending on it" need. The effect still reacts to the six filter/sort fields as intended; it no longer reacts to its owngoto()call.Test plan
fefe056(pre-gamification) — confirmed unrelated to this week's worksyncUrl()with a call counter — confirmed unbounded re-entry with identical state on every call before the fix/app/books,/app/gamesrender correctly and load real data, console is clean (no throttling warnings), a hard reload workspnpm --filter @loomkeep/web exec svelte-check— cleanpnpm --filter @loomkeep/api exec tsc --noEmit— clean (unaffected by this change, verified as part of the same pre-push run)Next steps once this merges
The VPS is currently in manual maintenance mode (Logan). Once this is deployed, maintenance can come off. This should merge and deploy independently of the gamification PRs (#178 already merged; #179/#181 pending) — none of them touch
LibraryBrowser.svelte.🤖 Generated with Claude Code