fix: infinite /partial request loop triggered by search input - #3863
Conversation
baed620 to
d91bb5a
Compare
gcgoncalves
left a comment
There was a problem hiding this comment.
Tested and working fine! :)
vishu-bh
left a comment
There was a problem hiding this comment.
LGTM 🚀
The fix looks correct, the regression coverage is targeted
a22f190 to
154c0ba
Compare
gcgoncalves
left a comment
There was a problem hiding this comment.
Tested and works fine. The code is correct and the proper tests were added.
gcgoncalves
left a comment
There was a problem hiding this comment.
Have you considered using the createMemoizedInit function? I created it for a similar init loop, and the goal back then was to apply it to all inits, to prevent exactly this loop issue.
|
@gcgoncalves It already implements the const {
init: initializeSearchInputsMemoized,
debouncedInit: initializeSearchInputsDebounced,
reset: resetSearchInputsState,
} = createMemoizedInit(initializeSearchInputs, 300, "SearchInputs");The fix works by:
The key change in the diff shows:BEFORE (caused infinite loop): document.body.addEventListener("htmx:afterSwap", function (event) {
resetSearchInputsState(); // ❌ This bypassed memoization guards
initializeSearchInputsDebounced(); // ❌ Triggered reload → swap → repeat
});AFTER (fixed): document.body.addEventListener("htmx:afterSwap", function (event) {
updateFilterStatus(); // ✅ Only updates UI, no re-init
});No changes needed - the implementation already follows the suggested pattern. |
Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
…lic registry Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
Update stale doc comment on initializeSearchInputs() to reflect that HTMX handlers no longer re-invoke it. Prefix unused entityType parameter with underscore to satisfy linter. Add URL cleanup in beforeEach to prevent test contamination on mid-test failures. Signed-off-by: Jonathan Springer <jps@s390x.com>
f94402c to
6c8263d
Compare
* fix: infinite /partial request loop triggered by search input Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: merging conflicts Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: npm deps for high vulnerabilities Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: package-lock.json file Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: E401 authentication error on npm install and pointing to the public registry Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: package-lock.json file Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: improve search init comments, lint, and test robustness Update stale doc comment on initializeSearchInputs() to reflect that HTMX handlers no longer re-invoke it. Prefix unused entityType parameter with underscore to satisfy linter. Add URL cleanup in beforeEach to prevent test contamination on mid-test failures. Signed-off-by: Jonathan Springer <jps@s390x.com> --------- Signed-off-by: Marek Dano <Marek.Dano@ibm.com> Signed-off-by: Jonathan Springer <jps@s390x.com> Co-authored-by: Marek Dano <Marek.Dano@ibm.com> Co-authored-by: Jonathan Springer <jps@s390x.com>
* fix: infinite /partial request loop triggered by search input Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: merging conflicts Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: npm deps for high vulnerabilities Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: package-lock.json file Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: E401 authentication error on npm install and pointing to the public registry Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: package-lock.json file Signed-off-by: Marek Dano <Marek.Dano@ibm.com> * fix: improve search init comments, lint, and test robustness Update stale doc comment on initializeSearchInputs() to reflect that HTMX handlers no longer re-invoke it. Prefix unused entityType parameter with underscore to satisfy linter. Add URL cleanup in beforeEach to prevent test contamination on mid-test failures. Signed-off-by: Jonathan Springer <jps@s390x.com> --------- Signed-off-by: Marek Dano <Marek.Dano@ibm.com> Signed-off-by: Jonathan Springer <jps@s390x.com> Co-authored-by: Marek Dano <Marek.Dano@ibm.com> Co-authored-by: Jonathan Springer <jps@s390x.com>
🐛 Bug-fix PR
Closes #3861
📌 Summary
Fix infinite loop of
/partialendpoint requests triggered when typing in admin UI search bars (servers, tools, resources, gateways, prompts, agents).Remove unnecessary search input re-initialization from
htmx:afterSwapandhtmx:afterSettlehandlers, since search inputs live outside the swapped table DOM and persist across partial refreshes.Fix npm high vulnerabilities
🔁 Reproduction Steps
Root Cause
initializeSearchInputs()attached the input event listener before setting.valuefrom URL state, so the value assignment immediately fired the listener, queuing a/partialreload whose swap re-initialized inputs — creating an infinite cycle💡 Fix Description
Changes
initializeSearchInputs()— set.valuebefore adding the input listener so initialization doesn't trigger a reloadhtmx:afterSwap— search inputs are not part of the swapped table content; only update filter statushtmx:afterSettle— same reasoning; only update filter statusloadSearchablePanelcall, but the server already returns correctly filtered data in the initial page loadtests/js/admin-search-init-loop.test.js, 7 tests) covering:- Value restoration from URL state does not fire the input listener
- No
htmx.ajaxcall is made during initialization- User typing still triggers a debounced
/partialreload (positive test)-
htmx:afterSwap/htmx:afterSettleon table targets do not re-trigger search initialization- Search input value and listener survive table content swaps
npm audit fixto fix high vulnerabilities🧪 Verification
make lintmake testmake coverage📐 MCP Compliance (if relevant)
✅ Checklist
make black isort pre-commit)