80ab15c036bf35894b59df383c03c51cbeff30be
chmalee
  Thu May 14 10:29:53 2026 -0700
Stop myVariants from clobbering regular custom tracks by giving it its own cart variable (mvCtfile_<db>) instead of overloading ctfile_<db>, refs #37553

diff --git src/hg/lib/myVariants.c src/hg/lib/myVariants.c
index 85a7c750a60..1ea8eb03d54 100644
--- src/hg/lib/myVariants.c
+++ src/hg/lib/myVariants.c
@@ -929,59 +929,66 @@
 }
 
 boolean myVariantsHandleCtRemoval(struct customTrack *ct, struct cart *cart,
                                   char *database)
 /* If ct is a myVariants own track: delete the user's rows for the current
  * assembly, unlink the persistent ctfile, drop the per-db renamed labels
  * and the visibility var.  If ct is a myVariants shared track: drop the
  * share-acceptance cart var and the visibility var.  Returns TRUE when ct
  * was a myVariants track and this function fully handled the cart cleanup
  * (caller must skip its own per-track cart cleanup so other-assembly
  * labels are preserved); FALSE otherwise. */
 {
 if (ct == NULL || ct->tdb == NULL || isEmpty(ct->tdb->track))
     return FALSE;
 char *trackName = ct->tdb->track;
+if (!startsWith("myVariants_", trackName))
+    return FALSE;
+
+/* Cleanup common to any myVariants removal: drop the track's visibility var
+ * and invalidate the on-disk ctfile pointer so the next entry-point visit
+ * regenerates from current SQL/share state. */
+cartRemove(cart, trackName);
+char mvVar[256];
+safef(mvVar, sizeof mvVar, MYVARIANTS_FILE_VAR_PREFIX "%s", database);
+cartRemove(cart, mvVar);
+
 if (startsWith("myVariants_shared_", trackName))
     {
+    /* Drop the share-acceptance var so the share isn't re-imported. */
     char *token = trackName + strlen("myVariants_shared_");
     char shareCartVar[256];
     safef(shareCartVar, sizeof shareCartVar,
         MYVAR_SHARED_CART_PREFIX "%s", token);
     cartRemove(cart, shareCartVar);
-    cartRemove(cart, trackName);
     return TRUE;
     }
-if (startsWith("myVariants_", trackName))
-    {
+
+/* Own track: delete the user's SQL rows for this assembly, unlink the
+ * persisted ctfile, and drop any renamed-label cart vars so a freshly
+ * created track on this assembly starts at "My Annotations" again. */
 char *userName = wikiLinkUserName();
 if (isNotEmpty(userName))
     {
     myVariantsDeleteForDb(userName, database);
     myVariantsUnlinkCtFile(userName, database);
     }
-    /* Drop the per-db renamed labels so a freshly created track on this
-     * assembly starts at "My Annotations" again.  Labels for other
-     * assemblies stay because they belong to different displayed tracks. */
 char labelPrefix[256];
 safef(labelPrefix, sizeof labelPrefix, "%s.%s.", trackName, database);
 cartRemovePrefix(cart, labelPrefix);
-    cartRemove(cart, trackName);
 return TRUE;
 }
-return FALSE;
-}
 
 struct slName *myVariantsGetProjects(char *userName)
 /* Return list of distinct non-empty project values for this user's myVariants table.
  * Caller must slFreeList the result. Returns NULL if no projects or table doesn't exist. */
 {
 if (isEmpty(userName))
     return NULL;
 
 char *dbTable = myVariantsTableExists(userName);
 if (isEmpty(dbTable))
     return NULL;
 
 struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
 struct slName *projects = NULL;
 char query[512];