32fbe1660c603d64e8210df9cc041ecb8feb3f38
hiram
  Mon Sep 21 09:07:43 2026 -0700
protect against a NULL cart from API search functions refs #38393

diff --git src/hg/cgilib/cartJson.c src/hg/cgilib/cartJson.c
index 56fc9ebbb00..42da4c3c5cc 100644
--- src/hg/cgilib/cartJson.c
+++ src/hg/cgilib/cartJson.c
@@ -69,31 +69,33 @@
     }
 return textIn;
 }
 
 void hgPositionsJson(struct jsonWrite *jw, char *db, struct hgPositions *hgp, struct cart *cart)
 /* Write out JSON description of multiple position matches. */
 {
 struct hgPosTable *table;
 jsonWriteListStart(jw, "positionMatches");
 struct trackDb *tdbList = NULL;
 // Opened lazily, on the first RefSeq/refGene hit (most searches never need it), and
 // sharing tdbList with the tdbForTrack calls below so it costs at most one extra
 // trackDb load per request, not a second one on top of theirs.
 struct maneLookup *maneLookup = NULL;
 boolean maneLookupAttempted = FALSE;
-boolean measureTiming = cartUsualBoolean(cart, "measureTiming", FALSE);
+boolean measureTiming = FALSE;
+if (cart)
+    measureTiming = cartUsualBoolean(cart, "measureTiming", FALSE);
 long maneLookupTimeMs = 0;
 for (table = hgp->tableList; table != NULL; table = table->next)
     {
     if (table->posList != NULL)
         {
         char *trackName = table->name, *tableName = table->name;
         struct trackDb *tdb = NULL;
         // these are pseudo-table names with no trackDb entry to look up. chromInfo is what
         // hgFind uses for a plain position range or a genomic HGVS match
         if (! (sameString("trackDb", tableName) || sameString("helpDocs", tableName) ||
                 sameString("publicHubs", tableName) || sameString("chromInfo", tableName)))
             {
             // a native tdbList carried over from an earlier table won't hold hub tracks,
             // drop it so tdbForTrack takes its hub lookup path
             if (isHubTrack(tableName))