-
Notifications
You must be signed in to change notification settings - Fork 739
Description
Bug report
Expected behavior and actual behavior
When using errorStrategy ignore
, it is possible for a published channel to be entirely empty. This is not inherently an issue. However, we have encountered a circumstance in which it raises a groovy error, causing the nextflow process to fail. I have created a minimal example to reproduce the error, which appears to driven the publication of an empty value channel.
Steps to reproduce the problem
nextflow.preview.output = true
process TEST {
errorStrategy 'ignore'
maxRetries 0
input:
val x
output:
path "${x}.txt", emit: demo
script:
"""
touch ${x}.txt
exit 1
"""
}
workflow {
main:
ch_demo = TEST(Channel.value(1)).demo // <- HERE IS THE CRITICAL SECTION
println ch_demo.getClass()
ch_demo.view()
publish:
demo = ch_demo
}
output {
demo {
contentType true
path { file ->
file >> "subdir/demo.txt"
}
}
}
Program output
In this example, the process is designed to fail. When the Process is provided with a queue channel Channel.from(1)
, it returns an empty queue channel and no error is encountered. When the Process is provided with a value channel Channel.value(1)
, it returns an empty value channel and the error is raised.
[8d/ff825f] process > TEST [100%] 1 of 1, ignored: 1 ✔
class groovyx.gpars.dataflow.DataflowVariable
[8d/ff825f] NOTE: Process `TEST` terminated with an error exit status (1) -- Error is ignored
ERROR ~ Cannot access first() element from an empty List
-- Check '.nextflow.log' file for details
The relevant section from .nextflow.log
:
Oct-07 18:26:35.269 [Actor Thread 9] ERROR nextflow.extension.OperatorImpl - @unknown
java.util.NoSuchElementException: Cannot access first() element from an empty List
at org.codehaus.groovy.runtime.DefaultGroovyMethods.first(DefaultGroovyMethods.java:10343)
at nextflow.extension.PublishOp.onComplete(PublishOp.groovy:197)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
at groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
at groovy.lang.Closure.call(Closure.java:433)
at groovy.lang.Closure.call(Closure.java:422)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
at nextflow.extension.DataflowHelper$3.afterStop(DataflowHelper.groovy:257)
at groovyx.gpars.dataflow.operator.DataflowProcessor.fireAfterStop(DataflowProcessor.java:324)
at groovyx.gpars.dataflow.operator.DataflowProcessorActor.afterStop(DataflowProcessorActor.java:59)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:633)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:624)
at groovyx.gpars.actor.Actor.callDynamic(Actor.java:369)
at groovyx.gpars.actor.Actor.handleTermination(Actor.java:320)
at groovyx.gpars.actor.AbstractLoopingActor.terminate(AbstractLoopingActor.java:204)
at groovyx.gpars.dataflow.operator.DataflowProcessor.terminate(DataflowProcessor.java:147)
at groovyx.gpars.dataflow.operator.DataflowProcessorActor.checkPoison(DataflowProcessorActor.java:115)
at groovyx.gpars.dataflow.operator.DataflowOperatorActor.onMessage(DataflowOperatorActor.java:83)
at groovyx.gpars.actor.impl.SDAClosure$1.call(SDAClosure.java:43)
at groovyx.gpars.actor.AbstractLoopingActor.runEnhancedWithoutRepliesOnMessages(AbstractLoopingActor.java:293)
at groovyx.gpars.actor.AbstractLoopingActor.access$400(AbstractLoopingActor.java:30)
at groovyx.gpars.actor.AbstractLoopingActor$1.handleMessage(AbstractLoopingActor.java:93)
at groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Oct-07 18:26:35.271 [main] DEBUG nextflow.Session - Session await > all processes finished
Oct-07 18:26:35.279 [Actor Thread 9] DEBUG nextflow.Session - Session aborted -- Cause: Cannot access first() element from an empty List
Environment
- Nextflow version:
25.04.6.5954
- Java version:
openjdk 17.0.16 2025-07-15
OpenJDK Runtime Environment (build 17.0.16+8-Ubuntu-0ubuntu122.04.1)
OpenJDK 64-Bit Server VM (build 17.0.16+8-Ubuntu-0ubuntu122.04.1, mixed mode, sharing)
- Operating system: Ubuntu
- Bash version:
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Additional context
In our use case, we use a Process to aggregate results from many tasks into a single results file. That file is then passed into a summary Process which emits a more user-friendly form of those results. We encounter the bug when all of the input tasks fail. This is uncommon, and primarily encountered during development.