412b01f1c0c78dd890c3d0d00fc121727e6085dd
max
  Fri Apr 10 05:59:34 2026 -0700
warn on column count mismatch in sampleMetadataFile parsing, refs #37334

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

diff --git src/hg/hgc/vcfClick.c src/hg/hgc/vcfClick.c
index 6570da1f50b..eaabf39d65d 100644
--- src/hg/hgc/vcfClick.c
+++ src/hg/hgc/vcfClick.c
@@ -265,32 +265,46 @@
 chopByChar(line, '\t', allCols, colCount);
 // Column 0 is sample name; metadata columns start at 1
 int metaColCount = colCount - 1;
 if (metaColCount < 1)
     {
     lineFileClose(&lf);
     return;
     }
 char **colNames;
 AllocArray(colNames, metaColCount);
 int i;
 for (i = 0; i < metaColCount; i++)
     colNames[i] = cloneString(allCols[i+1]);
 // Read data lines
 struct hash *hash = hashNew(0);
+boolean warnedExtra = FALSE, warnedFewer = FALSE;
 while (lineFileNext(lf, &line, &lineSize))
     {
+    int actualFieldCount = countChars(line, '\t') + 1;
+    if (!warnedExtra && actualFieldCount > colCount)
+        {
+        warn("sampleMetadataFile %s line %d: data row has %d columns but header defines only %d",
+            fileName, lf->lineIx, actualFieldCount, colCount);
+        warnedExtra = TRUE;
+        }
+    if (!warnedFewer && actualFieldCount < colCount)
+        {
+        warn("sampleMetadataFile %s line %d: data row has only %d columns but header defines %d",
+            fileName, lf->lineIx, actualFieldCount, colCount);
+        warnedFewer = TRUE;
+        }
     char *row[colCount];
     int fieldCount = chopByChar(line, '\t', row, colCount);
     if (fieldCount < 2)
         continue;
     struct sampleMeta *sm;
     AllocVar(sm);
     AllocArray(sm->values, metaColCount);
     for (i = 0; i < metaColCount && i + 1 < fieldCount; i++)
         sm->values[i] = cloneString(row[i+1]);
     hashAdd(hash, row[0], sm);
     }
 lineFileClose(&lf);
 *retHash = hash;
 *retColNames = colNames;
 *retColCount = metaColCount;