99c145df11c04f80820690fd67e9499f296b4d7d braney Sat Aug 1 12:58:39 2026 -0700 harvesters: resolve #defines per file, not pooled refs #37923 refs #37925 refs #37838 The first nightly run reported a new URL parameter, hggw_term, that had been in the tree since the hgGateway redesign. It was not new; the harvester had been answering the question differently in two checkouts of the same commit. SEARCH_TERM is "hggw_term" in hgGateway and "hgcd_term" in hgChooseDb. The #define table was pooled across the whole tree with setdefault, so the winner was whichever file the filesystem walk reached first, and hgGateway's reads came out as hgcd_term in my working tree and hggw_term in a fresh clone. For a nightly cron that means mail whenever a directory listing changes order, which is worse than no cron. So a name a file defines itself now wins, and a name the tree defines inconsistently resolves to {NAME} instead of to a guess. This is the call bdc473369e1 already made for char * constants, for the same reason and with the same tradeoff written up in the CONST_RE comment: an honest {ident} beats a confident wrong answer. Verified by harvesting both trees and diffing. Twelve names leave the URL baseline as a result, the gisaidTable and hgg_ prefix families, which were pooled values from sibling CGIs rather than reads in the file they were attributed to. Recovering those properly means following the #include chain to the header that defines them, which is not done here. The URL catalog carried hgt_tSearch twice, once correctly as the track search variable and once as hgGateway's search term, which was this bug showing up in the curated half. --check did not catch the duplicate because it only looks within a section. hgGateway now has hggw_term and hgChooseDb hgcd_term, both confirmed at their call sites and in their CGI's excludeVars. diff --git src/hg/utils/urlCommandCatalog/urlCommandCatalog.py src/hg/utils/urlCommandCatalog/urlCommandCatalog.py index 2cf4b8f915f..3c0118beb1c 100755 --- src/hg/utils/urlCommandCatalog/urlCommandCatalog.py +++ src/hg/utils/urlCommandCatalog/urlCommandCatalog.py @@ -862,33 +862,42 @@ note="Re-render the results already in the cart, rather than " "running a new search. How the banner and the table's " "'Old BLAT result page' link switch format without " "resubmitting the query."), c("wp_f", "action", "hg/hgPcr/hgPcr.c:847", value="", public=True, verified=True, note="Forward primer."), c("wp_r", "action", "hg/hgPcr/hgPcr.c:847", value="", public=True, verified=True, note="Reverse primer."), c("wp_showPage", "action", "hg/hgPcr/hgPcr.c:847", verified=True), ], }, "hgGateway / hgSearch / hgChooseDb": { "what": "The gateway and search pages, which share a cartJson command " "channel.", "cmds": [ - c("hgt_tSearch", "action", "hg/hgGateway/hgGateway.c:1250", + c("hggw_term", "action", "hg/hgGateway/hgGateway.c:1254", value="", verified=True, - note="Search term. Same variable name the track search uses."), + note="Species or assembly search term for the gateway's " + "autocomplete. Read before the cart is loaded, to keep the " + "lookup fast, and in hgGateway's excludeVars. Spelled " + "SEARCH_TERM in the source, which is why this row used to " + "say hgt_tSearch: that name is the track search's, and a " + "pooled #define table answered for both."), + c("hgcd_term", "action", "hg/hgChooseDb/hgChooseDb.c:224", + value="", verified=True, + note="The same search term on hgChooseDb, which spells its own " + "SEARCH_TERM differently. In that CGI's excludeVars."), c("cjCmd", "action", "hg/inc/cartJson.h:11", value="", verified=True, note="cartJson command channel, used by the page's own AJAX."), c("search", "action", "hg/hgSearch/hgSearch.c:563", value="", public=True, verified=True, leaks=True, note="Search term for the search results page."), ], }, "hgIntegrator / hgVai": { "what": "Data Integrator and Variant Annotation Integrator.", "cmds": [ c("hgi_doQuery", "action", "hg/hgIntegrator/hgIntegrator.c:48", verified=True, note="Run the integrator query."), c("hgva_startQuery", "action", "hg/hgVai/hgVai.c:68", verified=True, note="Run the annotation query."),