94041c12e043016875ebd340568bda0ccaf122f6
lrnassar
  Wed Jul 8 13:53:22 2026 -0700
Add db= to cross-CGI hgTracks/hgTrackUi/hgc links to prevent wrong-assembly errors. refs #37840

Completes the incomplete work from #26892: links from the browser to a different
CGI omitted db=, so the target CGI fell back to the cart's db (often wrong),
producing "Can't find <track> in track database <db>" errors and broken shared
links. Adds the current-assembly db to link builders across hgTracks
(chromGraphTrack, expRatioTracks, config ruler and per-track configure links,
variation), hgVai, hgFileUi, hgGtexTrackSettings, hgBlat, hgGene, hgNear, the
barChart/GTEx faceted UI (facetedBar, barChartUi, gtexUi), and the hgTrackUi
group-configure link.

diff --git src/hg/hgVai/hgVai.c src/hg/hgVai/hgVai.c
index a747bd46652..c4eb9141312 100644
--- src/hg/hgVai/hgVai.c
+++ src/hg/hgVai/hgVai.c
@@ -1064,32 +1064,32 @@
 	   "desirable to filter these annotations by cell type and/or score in order "
 	   "to avoid an overabundance of hits.  ");
     // Use a table with checkboxes in one column and label/other stuff that depends on
     // checkbox in other column.
     puts("<TABLE>");
     struct slRef *ref;
     for (ref = trackRefList;  ref != NULL;  ref = ref->next)
 	{
 	struct trackDb *tdb = ref->val;
 	char cartVar[512];
 	safef(cartVar, sizeof(cartVar), "hgva_track_%s_%s", database, tdb->track);
 	puts("<TR><TD valign=top>");
 	cartMakeCheckBox(cart, cartVar, FALSE);
 	puts("</TD><TD>");
 	struct trackDb *topTdb = trackDbTopLevelSelfOrParent(tdb);
-	printf("<A HREF=\"%s?%s&g=%s\">%s</A><BR>\n", hgTrackUiName(), cartSidUrlString(cart),
-	       topTdb->track, tdb->longLabel);
+	printf("<A HREF=\"%s?%s&db=%s&g=%s\">%s</A><BR>\n", hgTrackUiName(), cartSidUrlString(cart),
+	       database, topTdb->track, tdb->longLabel);
 	printFilterOptions(tdb);
 	puts("</TD></TR>");
 	}
     puts("</TABLE>");
     }
 }
 
 boolean isConsElTrack(struct trackDb *tdb, void *filterData)
 /* This is a TdbFilterFunction to get "phastConsNwayElements" tracks. */
 {
 return (startsWith("phastCons", tdb->table) && stringIn("Elements", tdb->table));
 }
 
 boolean isConsScoreTrack(struct trackDb *tdb, void *filterData)
 /* This is a TdbFilterFunction to get tracks that start with "phastCons" (no Elements)
@@ -1126,32 +1126,32 @@
 void trackCheckBoxSection(char *sectionSuffix, char *title, struct slRef *trackRefList)
 /* If trackRefList is non-NULL, make a collapsible section with a checkbox for each track,
  * labelled with longLabel. */
 {
 if (trackRefList != NULL)
     {
     startCollapsibleSection(sectionSuffix, title, FALSE);
     struct slRef *ref;
     for (ref = trackRefList;  ref != NULL;  ref = ref->next)
 	{
 	struct trackDb *tdb = ref->val;
 	char cartVar[512];
 	safef(cartVar, sizeof(cartVar), "hgva_track_%s_%s", database, tdb->track);
 	cartMakeCheckBox(cart, cartVar, FALSE);
 	struct trackDb *topTdb = trackDbTopLevelSelfOrParent(tdb);
-	printf("<A HREF=\"%s?%s&g=%s\">%s</A><BR>\n", hgTrackUiName(), cartSidUrlString(cart),
-	       topTdb->track, tdb->longLabel);
+	printf("<A HREF=\"%s?%s&db=%s&g=%s\">%s</A><BR>\n", hgTrackUiName(), cartSidUrlString(cart),
+	       database, topTdb->track, tdb->longLabel);
 	}
     puts("<BR>");
     endCollapsibleSection();
     }
 }
 
 void selectAnnotations(char *geneTrack)
 /* Beyond predictions of protein-coding effect, what other basic data can we integrate? */
 {
 struct slName *dbNsfpTables = findDbNsfpTables();
 boolean gotSnp = findSnpBed4("", NULL, NULL);
 struct slRef *elTrackRefList = NULL, *scoreTrackRefList = NULL;
 findCons(&elTrackRefList, &scoreTrackRefList);
 struct slRef *cosmicTrackRefList = findTrackRefByName("cosmic");
 boolean hasTxStat = hasTxStatus();