Symptom
On a 30-sample paired pooled run, merge-pairs emitted 60 warnings — one per sample per orientation, a 100% fire rate — on a run where the file lists were correctly aligned:
[merge-pairs] warning: forward dada '<...>/dada/R1/<sample>.json' was computed from
'<sample>.derep.R1.json.gz', but the forward FASTQ passed is '<sample>.R1.fastq.gz'
— check that the file lists line up
Cause
warn_on_input_mismatch (src/merge_pairs.rs:289-304) compares the input_file
recorded in the dada JSON against the basename of the FASTQ passed for that
orientation, by exact string equality:
if recorded != passed { eprintln!(...) }
When dada / dada-pooled / dada-pseudo is run from a derep JSON — the
normal path for pooled and pre-dereplicated workflows — the recorded name is
<sample>.derep.R1.json.gz while merge-pairs is necessarily passed
<sample>.R1.fastq.gz. Those strings can never be equal, so the warning fires
unconditionally regardless of whether the lists actually line up.
The check only behaves as designed when dada was handed the FASTQ directly.
Why it matters
The warning is meant to catch positional file lists drifting out of alignment
(e.g. a glob expanding to a different set), which would silently merge the wrong
samples. Firing on every sample of every correct run trains users to ignore it,
so it will not be noticed on the run where drift is real.
Note
The substantive guard is unaffected: check_sample_ids immediately below
compares the actual sample names and hard-errors on mismatch, so genuine list
drift is still caught. This issue is about the redundant check being useless
rather than a correctness hole.
Possible fixes
- Normalise both sides to a sample stem before comparing (strip known
.derep.<R>.json(.gz) / .fastq(.gz) / .fq(.gz) suffixes), and only warn
when the stems genuinely differ.
- Or: have
dada record the original FASTQ name alongside the derep input it
consumed, and compare against that.
- Or: drop the check entirely and rely on
check_sample_ids, which is a
stronger test and already hard-errors.
Whichever route, worth a regression test covering the derep-JSON-input path,
since that is the path the current check silently fails on.
Symptom
On a 30-sample paired pooled run,
merge-pairsemitted 60 warnings — one per sample per orientation, a 100% fire rate — on a run where the file lists were correctly aligned:Cause
warn_on_input_mismatch(src/merge_pairs.rs:289-304) compares theinput_filerecorded in the dada JSON against the basename of the FASTQ passed for that
orientation, by exact string equality:
When
dada/dada-pooled/dada-pseudois run from a derep JSON — thenormal path for pooled and pre-dereplicated workflows — the recorded name is
<sample>.derep.R1.json.gzwhilemerge-pairsis necessarily passed<sample>.R1.fastq.gz. Those strings can never be equal, so the warning firesunconditionally regardless of whether the lists actually line up.
The check only behaves as designed when
dadawas handed the FASTQ directly.Why it matters
The warning is meant to catch positional file lists drifting out of alignment
(e.g. a glob expanding to a different set), which would silently merge the wrong
samples. Firing on every sample of every correct run trains users to ignore it,
so it will not be noticed on the run where drift is real.
Note
The substantive guard is unaffected:
check_sample_idsimmediately belowcompares the actual sample names and hard-errors on mismatch, so genuine list
drift is still caught. This issue is about the redundant check being useless
rather than a correctness hole.
Possible fixes
.derep.<R>.json(.gz)/.fastq(.gz)/.fq(.gz)suffixes), and only warnwhen the stems genuinely differ.
dadarecord the original FASTQ name alongside the derep input itconsumed, and compare against that.
check_sample_ids, which is astronger test and already hard-errors.
Whichever route, worth a regression test covering the derep-JSON-input path,
since that is the path the current check silently fails on.