2ca5303deabc42182eae8cb7f49c2c8e9784eabf
jcasper
  Mon Mar 30 09:30:45 2026 -0700
Added an error message for when the metadata file is missing for
a faceted composite, refs #36320

diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c
index 9d840663ce3..39795676045 100644
--- src/hg/hgTrackUi/hgTrackUi.c
+++ src/hg/hgTrackUi/hgTrackUi.c
@@ -4181,38 +4181,47 @@
     }
 
 if (!matchFound)
     {
     puts("Status: 400 Bad Request");
     errAbort("Supplied fileUrl does not match any connected hubs or track settings.");
     }
 
 // By now we know that fileUrl points to something valid to fetch and return to the user.
 // Now we just have to fetch the file contents and retransmit it.
 
 int timeout = cartUsualInt(cart, "udcTimeout", 300);
 if (udcCacheTimeout() < timeout)
     udcSetCacheTimeout(timeout);
 
+struct udcFile *udc = udcFileMayOpen(fileUrl, NULL);
+if (udc == NULL)
+    {
+    puts("Status: 404 Not Found");
+    puts("Content-Type: text/plain\n");
+    printf("Error: could not open %s\n", fileUrl);
+    freeMem(fileUrl);
+    return;
+    }
+
 char maxAge[1024];
 safef(maxAge, sizeof(maxAge), "max-age=%d", timeout);
 printf("Cache-Control: %s\n", maxAge);
 
 // See if we're getting a "has it changed" request.
 // If so, return a 304 if nothing changed.
 char etag[1024];
-struct udcFile *udc = udcFileOpen(fileUrl, NULL);
 time_t mtime = udcUpdateTime(udc);
 safef(etag, sizeof(etag), "\"%ld\"", mtime);
 printf("ETag: %s\n", etag);
 udcFileClose(&udc);
 
 char *ifNone = getenv("HTTP_IF_NONE_MATCH");
 if (isNotEmpty(ifNone))
     {
     if (sameStringN(etag, ifNone, strlen(etag)-1)) // Apache can add -gzip to etags during transmission
         {
         puts("Status: 304 Not Modified\n");
         freeMem(fileUrl);
         return;
         }
     }