a44642a3a2f8ce803f75233cbc67b50a04a7614b
braney
  Fri May 1 12:46:58 2026 -0700
hgTracks: validate decorator bigDataUrl against quickLiftDb when present

loadDecorators was passing the current target db to isValidBigDataUrl, but
quickLifted tracks have decorator bigDataUrls under /gbdb/<sourceDb>/...,
matching the source assembly. Mirror the substitution already done in
isTrackForParallelLoad so decorator validation does not errAbort on
quickLifted tracks.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 399f739f5bf..a7ebc4f7e5d 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -8062,46 +8062,52 @@
     return 1;
     }
 return 0;
 }
 
 
 void loadDecorators(struct track *track)
 /* Load decorations from a source (file) and put them into decorators, then add those
  * decorators to the list of the track's decorators.  Within the new decorators, each
  * of the decorations should have been entered into a hash table that is indexed by the
  * name of the linked feature.  That way when we're drawing the linked feature, we'll
  * be able to quickly locate the associated decorations.
  */
 {
 struct trackDb *decoratorTdbs = getTdbsForDecorators(track->tdb);
+// quickLifted tracks fetch from the source assembly, so their decorator
+// bigDataUrls live under /gbdb/<sourceDb>/... -- validate against that.
+char *decoratorDb = database;
+char *quickLiftDb = trackDbSetting(track->tdb, "quickLiftDb");
+if (quickLiftDb != NULL)
+    decoratorDb = quickLiftDb;
 for (struct trackDb *decoratorTdb = decoratorTdbs; decoratorTdb != NULL;
         decoratorTdb = decoratorTdb->next)
     {
     char *decoratorUrl = trackDbSetting(decoratorTdb, "bigDataUrl");
     if (!decoratorUrl)
         {
         warn ("Decorator tags are present as %s, but no decorator file specified (bigDataUrl is missing)",
                 decoratorTdb->track);
         continue;
         }
 
     struct bbiFile *bbi = NULL;
     struct errCatch *errCatch = errCatchNew();
     if (errCatchStart(errCatch))
         {
-        if (isValidBigDataUrl(decoratorUrl,TRUE, database, TRUE))
+        if (isValidBigDataUrl(decoratorUrl,TRUE, decoratorDb, TRUE))
             bbi = bigBedFileOpenAlias(decoratorUrl, chromAliasFindAliases);
         }
     errCatchEnd(errCatch);
     if (errCatch->gotError)
         {
         warn ("Network error while attempting to retrieve decorations from %s (track %s) - %s",
                 decoratorUrl, track->track, dyStringContents(errCatch->message));
         continue;
         }
     errCatchFree(&errCatch);
 
     struct asObject *decoratorFileAsObj = asParseText(bigBedAutoSqlText(bbi));
     if (!asColumnNamesMatchFirstN(decoratorFileAsObj, decorationAsObj(), DECORATION_NUM_COLS))
         {
         warn ("Decoration file associated with track %s (%s) does not match the expected format - see decoration.as",