Skip to content

Publish fails if it encounters an empty Value channel #6458

@mikesivley

Description

@mikesivley

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions