061f2211a2955946e5a15ca6109bf2c667c842ee
braney
  Fri May 15 08:19:51 2026 -0700
clear stale lastPosition when cart db changes so QuickLift/hgGateway hops don't trigger a
spurious "Unable to resolve lastPosition" banner on the destination assembly refs #37562

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index 7c17f2d96d7..efd41d38dd2 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -3002,30 +3002,41 @@
     if (link != NULL && !sameOk(link, "<>")) // "<>" means "default settings" = "no file"
         {
         htmlSetStyleTheme(link); // for htmshell.c, used by hgTracks
         webSetStyle(link);       // for web.c, used by hgc
         }
     }
 }
 
 void cartSetLastPosition(struct cart *cart, char *position, struct hash *oldVars)
 /* If position and oldVars are non-NULL, and oldVars' position is different, add it to the cart
  * as lastPosition.  This is called by cartHtmlShell{,WithHead} but not other cart openers;
  * it should be called after cartGetPosition or equivalent. */
 {
 if (position != NULL && oldVars != NULL)
     {
+    /* If db changed (e.g. QuickLift hop or hgGateway switch), the old position is from
+     * a different assembly and would fail to resolve here; clear any stale lastPosition
+     * instead of carrying it over. */
+    struct hashEl *oldDb = hashLookup(oldVars, "db");
+    char *newDb = cartOptionalString(cart, "db");
+    if (oldDb != NULL && newDb != NULL && !IS_CART_VAR_EMPTY(oldDb->val) &&
+        differentString(newDb, oldDb->val))
+        {
+        cartRemove(cart, "lastPosition");
+        return;
+        }
     struct hashEl *oldPos = hashLookup(oldVars, positionCgiName);
     if (oldPos != NULL && differentString(position, oldPos->val))
         cartSetString(cart, "lastPosition", oldPos->val);
     }
 }
 
 static void cartGenericStartup(struct cart *cart) 
 /* generic startup code to initialize settings from the cart when using either -WithHead or -MaybeContent cartShell functions */
 {
 setThemeFromCart(cart);
 googleAnalyticsSetGa4Key();
 
 int verbose = cgiOptionalInt("verbose", -1);
 if (verbose != -1)
     verboseSetLevel(verbose);