c9655cda984d9a119d0c4ee37505392fa853a224
max
  Thu Aug 6 05:47:02 2026 -0700
Move the orphaned range-filter warning from hgTrackUi to hubCheck, refs #37927

Per Brian's review comment: a new warning on the track config page makes hubs
that used to work look broken to whoever opens them, and the browser is the
wrong place to nag about it. Revert the hui.c warning and do the check in
hubCheck instead, where the hub author is the one reading the output.

The check now looks only at settings declared on the stanza itself, so an
orphaned filterByRange on a composite parent is reported once rather than
repeated for every subtrack. The filter.<field> lookup still walks up the
parent chain, so a subtrack that inherits its default range stays quiet.

diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index 905060ba5c6..03f819249e5 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -6949,81 +6949,41 @@
  * Try to guess what the user means. */
 {
 if (sameString("score", field))
     return 4;
 if (sameString("signal", field))
     return 6;
 if (sameString("signalValue", field))
     return 6;
 if (sameString("pValue", field))
     return 7;
 if (sameString("qValue", field))
     return 8;
 return -1;
 }
 
-static void warnOrphanedRangeFilters(struct trackDb *tdb)
-/* A numeric filter is only DISCOVERED from a filter.<field> (or <field>Filter)
- * setting -- see FILTER_NUMBER_WILDCARD and tdbGetTrackNumFilters(). A
- * filterByRange.<field> or filterLimits.<field> with no matching filter.<field>
- * is silently ignored and its control never appears, which is an easy and
- * confusing mistake to make. Warn so the track/hub developer sees why a filter
- * they configured did not show up. */
-{
-struct slName *orphans = slCat(trackDbSettingsWildMatch(tdb, "filterByRange.*"),
-                               trackDbSettingsWildMatch(tdb, "filterLimits.*"));
-struct hash *seen = hashNew(0);
-struct slName *s;
-for (s = orphans; s != NULL; s = s->next)
-    {
-    char *field = strchr(s->name, '.');
-    if (field == NULL)
-        continue;
-    field++; // skip past the '.'
-    if (hashLookup(seen, field) != NULL)
-        continue;
-    hashAdd(seen, field, NULL);
-    char setting[512];
-    safef(setting, sizeof setting, "filter.%s", field);
-    if (trackDbSettingClosestToHome(tdb, setting) != NULL)
-        continue;
-    safef(setting, sizeof setting, "%s%s", field, FILTER_NUMBER_NAME_CAP);
-    if (trackDbSettingClosestToHome(tdb, setting) != NULL)
-        continue;
-    warn("Track %s: a filterByRange/filterLimits setting exists for field '%s' "
-         "but there is no filter.%s (the default range), so this filter is not "
-         "shown. Add 'filter.%s min:max' to enable it.",
-         tdb->track, field, field, field);
-    }
-hashFree(&seen);
-slFreeList(&orphans);
-}
-
 static int numericFiltersShowAll(char *db, struct cart *cart, struct trackDb *tdb, boolean *opened,
                                  boolean boxed, boolean parentLevel,char *name, char *title,
                                  boolean isHighlight)
 // Shows all *Filter style filters.  Note that these are in random order and have no graceful title
 {
 int count = 0;
 struct trackDbFilter *trackDbFilters = NULL;
 if (isHighlight)
     trackDbFilters = tdbGetTrackNumHighlights(tdb);
 else
-    {
     trackDbFilters = tdbGetTrackNumFilters(tdb);
-    warnOrphanedRangeFilters(tdb);
-    }
 if (trackDbFilters)
     {
     puts("<BR>");
     struct trackDbFilter *filter = NULL;
     struct sqlConnection *conn = NULL;
     if (!isHubTrack(db))
         conn = hAllocConnTrack(db, tdb);
     struct asObject *as = asForTdb(conn, tdb);
     hFreeConn(&conn);
 
     while ((filter = slPopHead(&trackDbFilters)) != NULL)
         {
         char *field = filter->fieldName;
         char *scoreName = cloneString(filter->name);
         char *trackDbLabel = getLabelSetting(cart, tdb, field);