5bf1bd7150fc659d3a1bd9f34e4daad593728cb3
max
  Fri Sep 11 17:55:11 2026 -0700
refGene never got the transcript codon number: the genbank CDS tables are in hgFixed, so their names are database-qualified and hTableExists could not see them. Use sqlTableExists, which can, refs #38298

diff --git src/hg/hgTracks/cds.c src/hg/hgTracks/cds.c
index 555b964be27..ab0a63ea221 100644
--- src/hg/hgTracks/cds.c
+++ src/hg/hgTracks/cds.c
@@ -868,56 +868,60 @@
  * pslHash.  This has to come from the transcript's own annotation and not from the
  * alignment:  for ~800 transcripts on hg38 the alignment does not even reach the start of
  * the CDS, and anchoring on the alignment would quietly renumber from the wrong base. */
 {
 struct hashEl *el, *elList = hashElListHash(pslHash);
 if (elList == NULL)
     return;
 struct dyString *accs = dyStringNew(1024);
 int n = 0;
 for (el = elList;  el != NULL && n < 2000;  el = el->next, n++)
     {
     if (n > 0)
         sqlDyStringPrintf(accs, ",");
     sqlDyStringPrintf(accs, "'%s'", el->name);
     }
+struct sqlConnection *conn = hAllocConn(db);
 struct dyString *query = NULL;
 if (sameString(table, "ncbiRefSeqPsl") && hTableExists(db, "ncbiRefSeqCds"))
     query = sqlDyStringCreate("select id, cds from ncbiRefSeqCds where id in (%-s)",
                               accs->string);
-else if (hTableExists(db, gbCdnaInfoTable) && hTableExists(db, cdsTable))
+/* refGene's versionless accessions get their CDS from the genbank tables, which usually
+ * live in hgFixed, so these names arrive database-qualified and only sqlTableExists can
+ * see them; hTableExists looks inside db and would always say no. */
+else if (sameString(table, "refSeqAli") &&
+         sqlTableExists(conn, gbCdnaInfoTable) && sqlTableExists(conn, cdsTable))
     query = sqlDyStringCreate(
         "select g.acc, c.name from %s g, %s c where g.cds = c.id and g.acc in (%-s)",
         gbCdnaInfoTable, cdsTable, accs->string);
 if (query != NULL)
     {
-    struct sqlConnection *conn = hAllocConn(db);
     struct sqlResult *sr = sqlGetResult(conn, query->string);
     char **row;
     while ((row = sqlNextRow(sr)) != NULL)
         {
         struct genbankCds *cds;
         AllocVar(cds);
         if (genbankCdsParse(row[1], cds) && cds->start < cds->end)
             hashAdd(cdsHash, row[0], cds);
         else
             freez(&cds);
         }
     sqlFreeResult(&sr);
-    hFreeConn(&conn);
     dyStringFree(&query);
     }
+hFreeConn(&conn);
 dyStringFree(&accs);
 hashElFreeList(&elList);
 }
 
 static struct txAliWindow *txAliInWindow(char *db, char *table, char *chrom)
 /* Return the alignments overlapping this window and their transcripts' CDS.  Two queries
  * per table per window, the first on the bin index, and the window is never wide:  the
  * codon coloring this feeds only happens at zoomedToCdsColorLevel. */
 {
 static struct hash *windowHash = NULL;
 if (windowHash == NULL)
     windowHash = hashNew(0);
 char key[1024];
 safef(key, sizeof(key), "%s:%s:%s:%d:%d", db, table, chrom, winStart, winEnd);
 struct txAliWindow *tw = hashFindVal(windowHash, key);