Description of the bug
Description
Running nf-core/cutandrun (v3.2.2) with Nextflow 25.10.4 produced a parsing/runtime error originating from the trimgalore module:
ERROR ~ Cannot invoke method optional() on null object
-- Check script '.../modules/local/for_patch/trimgalore/main.nf' at line: 18
The offending original line was:
tuple val(meta), path("*.html"), emit: html optional true
Reproduction (example)
nextflow run nf-core/cutandrun -r 3.2.2 -c /path/to/config --input Samplesheet.csv ...
Root cause (summary)
A combination of subtle DSL parsing/evaluation order and slightly ambiguous syntax causes Nextflow/Groovy to evaluate tokens at parse-time that reference meta before input: has been processed, and to interpret optional true/emit: html ambiguously. This manifests as a NullPointerException on optional() and later No such property: meta errors.
Minimal patch that fixed it locally
We applied the following minimal, targeted changes to modules/local/for_patch/trimgalore/main.nf:
Move input: above tag (this was required on our setup so meta is defined before parse-time evaluations):
-process TRIMGALORE {
- tag { meta.id }
+process TRIMGALORE {
- input:
- tuple val(meta), path(reads)
- tag { meta?.id ?: task.process }
label 'process_high'
Make tag defensive (closure + safe navigation) to avoid throwing if meta is missing for any reason:
tag { meta?.id ?: task.process }
Quote emit names and make optional explicit:
- tuple val(meta), path("*trimmed.fastq.gz") , emit: reads
- tuple val(meta), path("*report.txt") , emit: log
- path "versions.yml" , emit: versions
- tuple val(meta), path("*.html"), emit: 'html', optional true
- tuple val(meta), path("*.zip") , emit: 'zip', optional true
- tuple val(meta), path("*trimmed.fastq.gz"), emit: 'reads'
- tuple val(meta), path("*report.txt"), emit: 'log'
- path "versions.yml", emit: 'versions'
- tuple val(meta), path("*.html"), emit: 'html', optional: true
- tuple val(meta), path("*.zip"), emit: 'zip', optional: true
Command used and terminal output
nextflow run nf-core/cutandrun -r 3.2.2 -c /path/to/config --input Samplesheet.csv ...
ERROR ~ Cannot invoke method optional() on null object
-- Check script '.../modules/local/for_patch/trimgalore/main.nf' at line: 18
Relevant files
No response
System information
Nextflow: 25.10.4
Java: OpenJDK 21.0.10
Pipeline: nf-core/cutandrun v3.2.2
Container engine: Singularity (HPC)
Description of the bug
Description
Running nf-core/cutandrun (v3.2.2) with Nextflow 25.10.4 produced a parsing/runtime error originating from the trimgalore module:
ERROR ~ Cannot invoke method optional() on null object
-- Check script '.../modules/local/for_patch/trimgalore/main.nf' at line: 18
The offending original line was:
tuple val(meta), path("*.html"), emit: html optional true
Reproduction (example)
nextflow run nf-core/cutandrun -r 3.2.2 -c /path/to/config --input Samplesheet.csv ...
Root cause (summary)
A combination of subtle DSL parsing/evaluation order and slightly ambiguous syntax causes Nextflow/Groovy to evaluate tokens at parse-time that reference meta before input: has been processed, and to interpret optional true/emit: html ambiguously. This manifests as a NullPointerException on optional() and later No such property: meta errors.
Minimal patch that fixed it locally
We applied the following minimal, targeted changes to modules/local/for_patch/trimgalore/main.nf:
Move input: above tag (this was required on our setup so meta is defined before parse-time evaluations):
-process TRIMGALORE {
+process TRIMGALORE {
label 'process_high'
Make tag defensive (closure + safe navigation) to avoid throwing if meta is missing for any reason:
tag { meta?.id ?: task.process }
Quote emit names and make optional explicit:
Command used and terminal output
Relevant files
No response
System information
Nextflow: 25.10.4
Java: OpenJDK 21.0.10
Pipeline: nf-core/cutandrun v3.2.2
Container engine: Singularity (HPC)