-
Notifications
You must be signed in to change notification settings - Fork 776
Description
Bug report
Expected behavior and actual behavior
Expected behavior: When a contributor in manifest.contributors omits the contribution field, Nextflow should either:
- Use a default value (e.g., empty list or
['contributor']) - Provide a clear error message indicating the missing required field
Actual behavior: Nextflow crashes with a NullPointerException that is difficult to debug, showing only:
ERROR ~ Cannot invoke "java.util.Collection.stream()" because "
Steps to reproduce the problem
- Create a
nextflow.configfile with contributors that omit thecontributionfield:
manifest {
name = "Test Workflow"
contributors = [
[
name: 'John Doe',
affiliation: 'Example University',
orcid: 'https://orcid.org/0000-0000-0000-0000'
]
]
}
process.container = 'ubuntu:latest'- Create a simple
main.nf:
#!/usr/bin/env nextflow
process Dummy {
debug true
script:
"echo 'Hello world!'"
}
workflow {
Dummy()
}- Run:
nextflow run .
Program output
N E X T F L O W ~ version 25.07.0-edge
ERROR ~ Cannot invoke "java.util.Collection.stream()" because "
-- Check '.nextflow.log' file for details
Complete stack trace from .nextflow.log:
java.lang.NullPointerException: Cannot invoke "java.util.Collection.stream()" because "
at nextflow.config.Manifest$Contributor.<init>(Manifest.groovy:211)
at nextflow.config.Manifest$_parseContributors_lambda1.doCall(Manifest.groovy:170)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at org.codehaus.groovy.runtime.StreamGroovyMethods.toList(StreamGroovyMethods.java:463)
at nextflow.config.Manifest.parseContributors(Manifest.groovy:169)
at nextflow.config.Manifest.<init>(Manifest.groovy:146)
at nextflow.scm.AssetManager.getManifest0(AssetManager.groovy:469)
at nextflow.scm.AssetManager.memoizedMethodPriv$getManifest(AssetManager.groovy:441)
...
at nextflow.cli.CmdRun.run(CmdRun.groovy:326)
at nextflow.cli.Launcher.run(Launcher.groovy:513)
at nextflow.cli.Launcher.main(Launcher.groovy:673)
Environment
- Nextflow version: 25.07.0-edge build 5954
- Java version: OpenJDK 64-Bit Server VM 21.0.8
- Operating system: macOS 15.6.1
- Bash version: GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)
Additional context
Root cause: In Manifest.groovy line 211, the Contributor constructor attempts to call .stream() on opts.contribution without null-checking:
contribution = (opts.contribution as List<String>).stream()
.map(c -> ContributionType.valueOf(c.toUpperCase()))
.sorted()
.toList()When opts.contribution is null (i.e., the field is omitted), (null as List<String>) results in null, and calling .stream() on null throws the NPE.
Documentation inconsistency: The documentation lists contribution as a supported field but doesn't clearly indicate it's required. However, the code implementation makes it functionally mandatory.
Suggested fix: Add null-safety handling:
contribution = opts.contribution ?
(opts.contribution as List<String>).stream()
.map(c -> ContributionType.valueOf(c.toUpperCase()))
.sorted()
.toList() :
[]