5ab68cb3e725251bdcd2d9b835883af146f72dc7
angie
  Tue May 14 12:55:56 2019 -0700
When loading custom tracks, if all have been removed then the ctfile_ var is also removed, so don't errAbort if it's gone.

diff --git src/hg/lib/customTrack.c src/hg/lib/customTrack.c
index 1d4cdd4..89937dd 100644
--- src/hg/lib/customTrack.c
+++ src/hg/lib/customTrack.c
@@ -938,31 +938,32 @@
     cartRemove(cart, CT_SELECTED_TABLE_VAR);
     }
 
 /* merge new and old tracks */
 numAdded = slCount(newCts);
 ctList = customTrackAddToList(ctList, newCts, &replacedCts, FALSE);
 for (ct = ctList; ct != NULL; ct = ct->next)
     if (trackDbSetting(ct->tdb, CT_UNPARSED))
         {
         ctRemoveFromSettings(ct, CT_UNPARSED);
         changedCt = TRUE;
         }
 if (newCts || removedCt || changedCt || ctConfigUpdate(ctFileName))
     {
     customTracksSaveCart(genomeDb, cart, ctList);
-    ctFileName = cartString(cart, customTrackFileVar(genomeDb));
+    // If all CTs have been removed then customTrackFileVar is also removed from cart, so optional:
+    ctFileName = cartOptionalString(cart, customTrackFileVar(genomeDb));
     }
 
 if (cgiScriptName() && !endsWith(cgiScriptName(),"hgCustom"))
     {
     /* filter out cts that are unavailable remote resources */
     ctList = customTrackRemoveUnavailableFromList(ctList);
     }
 
 cartRemove(cart, CT_CUSTOM_TEXT_ALT_VAR);
 cartRemove(cart, CT_CUSTOM_TEXT_VAR);
 cartRemove(cart, CT_CUSTOM_FILE_VAR);
 cartRemove(cart, CT_CUSTOM_FILE_NAME_VAR);
 cartRemove(cart, CT_CUSTOM_FILE_BIN_VAR);
 cartRemove(cart, CT_CUSTOM_DOC_FILE_BIN_VAR);