Bug report
The data-lineage docs present nextflow lineage diff as a way to understand why -resume re-ran a task. However, the lineage TaskRun record stores only a subset of the inputs that go into the task cache hash, so for changes in the omitted inputs the diff shows no meaningful difference even though the task was correctly re-executed.
The cache hash key (TaskHasher.compute()) includes, among others:
None of these has a corresponding field in the lineage TaskRun model (modules/nf-lineage/src/main/nextflow/lineage/model/v1beta1/TaskRun.groovy), which stores: sessionId, name, codeChecksum, script, input, container, conda, spack, architecture, globalVars, binEntries, workflowRun.
The module omission is the clearest: the record captures conda, spack, container and architecture but not module, even though all are environment inputs to the same hash.
Steps to reproduce
main.nf:
process GREET {
module 'samtools/1.9'
input: val name
output: path 'out.txt'
script: """ echo "Hello ${name}" > out.txt """
}
workflow { GREET(Channel.of('world')) }
nextflow.config:
nextflow run main.nf -dump-hashes
- Change only
samtools/1.9 to samtools/1.17
nextflow run main.nf -resume -dump-hashes — the task correctly re-runs
-dump-hashes pinpoints the change:
0a5461eb… [java.lang.String] samtools/1.9 (run 1)
bd743eeb… [java.lang.String] samtools/1.17 (run 2)
nextflow lineage diff <run1-taskrun> <run2-taskrun> shows only the parent run id changing — nothing about the module:
- "workflowRun": "lid://f54deed4…"
+ "workflowRun": "lid://4c89b0ed…"
The task LID is the task hash, so the two records necessarily have different LIDs, yet the diff surfaces no field that explains it.
Expected behaviour
The TaskRun record should capture the cache-hash inputs it currently omits, so that comparing two task runs reflects what actually invalidated the cache:
module (sits naturally beside conda / spack / container / architecture)
eval output commands
- a stub-run indicator (partially covered today, since
codeChecksum switches to the stub source under stub runs)
Note this would make lineage diff consistent with the cache hash, but not a full substitute for -dump-hashes: the record stores resolved values rather than the ordered hash-key list, and lineage DataPath checksums are always computed with the default hash mode, so under deep/lenient cacheMode the record can still diverge from the cache decision. -dump-hashes remains the authoritative tool.
Environment
- Nextflow version: confirmed on 26.04.3 (release) and reproduced in
master source (TaskHasher keys on module/eval/stub; the TaskRun v1beta1 model has fields for none of them)
- Java version: 21
- Lineage:
lineage.enabled = true
Related
A PR adding the module field follows; eval and stub are left for discussion since their representation needs a design decision.
Bug report
The data-lineage docs present
nextflow lineage diffas a way to understand why-resumere-ran a task. However, the lineageTaskRunrecord stores only a subset of the inputs that go into the task cache hash, so for changes in the omitted inputs the diff shows no meaningful difference even though the task was correctly re-executed.The cache hash key (
TaskHasher.compute()) includes, among others:moduledirectives (task.config.getModule())evaloutput commands (getOutputEvals(), added in Pipeline uses cached process despite edited eval script #5470)None of these has a corresponding field in the lineage
TaskRunmodel (modules/nf-lineage/src/main/nextflow/lineage/model/v1beta1/TaskRun.groovy), which stores:sessionId, name, codeChecksum, script, input, container, conda, spack, architecture, globalVars, binEntries, workflowRun.The
moduleomission is the clearest: the record capturesconda,spack,containerandarchitecturebut notmodule, even though all are environment inputs to the same hash.Steps to reproduce
main.nf:nextflow.config:nextflow run main.nf -dump-hashessamtools/1.9tosamtools/1.17nextflow run main.nf -resume -dump-hashes— the task correctly re-runs-dump-hashespinpoints the change:nextflow lineage diff <run1-taskrun> <run2-taskrun>shows only the parent run id changing — nothing about the module:The task LID is the task hash, so the two records necessarily have different LIDs, yet the diff surfaces no field that explains it.
Expected behaviour
The
TaskRunrecord should capture the cache-hash inputs it currently omits, so that comparing two task runs reflects what actually invalidated the cache:module(sits naturally besideconda/spack/container/architecture)evaloutput commandscodeChecksumswitches to the stub source under stub runs)Note this would make
lineage diffconsistent with the cache hash, but not a full substitute for-dump-hashes: the record stores resolved values rather than the ordered hash-key list, and lineageDataPathchecksums are always computed with the default hash mode, so underdeep/lenientcacheModethe record can still diverge from the cache decision.-dump-hashesremains the authoritative tool.Environment
mastersource (TaskHasherkeys onmodule/eval/stub; theTaskRunv1beta1 model has fields for none of them)lineage.enabled = trueRelated
A PR adding the
modulefield follows;evalandstubare left for discussion since their representation needs a design decision.