# Challenging Nextflow workflow - Need help please!

**URL:** <https://community.seqera.io/t/challenging-nextflow-workflow-need-help-please/1671>\
**Category:** Ask for help\
**Tags:** nextflow, nf-core\
**Created:** [January 28, 2025, 10:56pm UTC](https://community.seqera.io/t/challenging-nextflow-workflow-need-help-please/1671 "2025-01-28T22:56:55Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Arkajyoti\_Sarkar](https://dub1.discourse-cdn.com/flex013/user_avatar/community.seqera.io/arkajyoti_sarkar/32/1399_2.png) [@Arkajyoti\_Sarkar](https://community.seqera.io/u/Arkajyoti_Sarkar)\
**Post date:** [January 28, 2025, 10:56pm UTC](https://community.seqera.io/t/challenging-nextflow-workflow-need-help-please/1671/1 "2025-01-28T22:56:55Z")

</div>

Hi everyone,

I’m encountering an issue while running my Nextflow workflow written in DSL2. The error suggests there’s an “Unknown process directive: `path`”. Below, I’ve included my workflow script and the error log for reference.

### Nextflow Script:

```groovy
#!/usr/bin/env nextflow

nextflow.enable.dsl=2

params.input_dir
params.output_dir
params.diameter_w0
params.diameter_w1
params.flow_threshold_w0
params.flow_threshold_w1

workflow {
    if (!params.input_dir || !params.output_dir || !params.diameter_w0 || !params.diameter_w1 || !params.flow_threshold_w0 || !params.flow_threshold_w1) {
        error "All parameters must be provided."
    }

    def (w0, w1) = processCellpose(
        params.input_dir,
        params.output_dir,
        params.diameter_w0,
        params.diameter_w1,
        params.flow_threshold_w0,
        params.flow_threshold_w1
    )

    w0.view { "w0 channel: $it" }
    w1.view { "w1 channel: $it" }

    processPlotting(
        w0,
        w1,
        params.input_dir,
        params.output_dir
    )
}

process processCellpose {
    container 'cellpose_env:latest'
    input:
        val input_dir
        val output_dir
        val diameter_w0
        val diameter_w1
        val flow_threshold_w0
        val flow_threshold_w1
    output:
        tuple(
            path("w0").optional(),
            path("w1").optional()
        )
    script:
    """
    python /app/cellpose_2ch.py \
        --input_dir $input_dir \
        --output_dir $PWD \
        --diameter_w0 $diameter_w0 \
        --diameter_w1 $diameter_w1 \
        --flow_threshold_w0 $flow_threshold_w0 \
        --flow_threshold_w1 $flow_threshold_w1
    mkdir -p ${output_dir}/w0
    mkdir -p ${output_dir}/w1
    mv w0/* ${output_dir}/w0/ || echo "No files in w0"
    mv w1/* ${output_dir}/w1/ || echo "No files in w1"
    """
}

process processPlotting {
    container 'plotting_env:latest'
    input:
        path w0
        path w1
        val input_dir
        val output_dir
    output:
        path("${output_dir}/results")
    script:
    """
    python /app/nuc_quant.py \
        --w0 $w0 \
        --w1 $w1 \
        --output_rois ${output_dir}/rois \
        --output_excel ${output_dir}/excel \
        --output_graphs ${output_dir}/graphs \
        --intensity_images $input_dir
    """
}

```

### Error Log:

```plaintext
(base) arka@Dell:~/Desktop/Nextflow_projects/BR_nf$ cat .nextflow.log
Jan-28 22:15:39.686 [main] DEBUG nextflow.cli.Launcher - $> nextflow run workflow.nf --input_dir /home/arka/Desktop/Nextflow_projects/BR_nf/input_images --output_dir /home/arka/Desktop/Nextflow_projects/BR_nf/output --diameter_w0 20 --diameter_w1 11.9 --flow_threshold_w0 0.8 --flow_threshold_w1 0.6
Jan-28 22:15:39.835 [main] DEBUG nextflow.cli.CmdRun - N E X T F L O W ~ version 24.10.4
Jan-28 22:15:39.862 [main] DEBUG nextflow.plugin.PluginsFacade - Setting up plugin manager > mode=prod; embedded=false; plugins-dir=/home/arka/.nextflow/plugins; core-plugins: nf-amazon@2.9.2,nf-azure@1.10.2,nf-cloudcache@0.4.2,nf-codecommit@0.2.2,nf-console@1.1.4,nf-google@1.15.3,nf-tower@1.9.3,nf-wave@1.7.4
Jan-28 22:15:39.886 [main] INFO o.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
Jan-28 22:15:39.888 [main] INFO o.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
Jan-28 22:15:39.892 [main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.12.0 in 'deployment' mode
Jan-28 22:15:39.911 [main] INFO org.pf4j.AbstractPluginManager - No plugins
Jan-28 22:15:39.973 [main] DEBUG n.secret.LocalSecretsProvider - Secrets store: /home/arka/.nextflow/secrets/store.json
Jan-28 22:15:39.988 [main] DEBUG nextflow.secret.SecretsLoader - Discovered secrets providers: [nextflow.secret.LocalSecretsProvider@1bd81830] - activable => nextflow.secret.LocalSecretsProvider@1bd81830
Jan-28 22:15:40.060 [main] DEBUG nextflow.cli.CmdRun - Applied DSL=2 from script declaration
Jan-28 22:15:40.085 [main] DEBUG nextflow.cli.CmdRun - Launching `workflow.nf` [ridiculous_hoover] DSL2 - revision: 3a841c6dd5
Jan-28 22:15:40.087 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins default=[]
Jan-28 22:15:40.088 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins resolved requirement=[]
Jan-28 22:15:40.196 [main] DEBUG nextflow.Session - Session UUID: f0b82bc6-b354-40c8-a8e2-7f50728d7e1e
Jan-28 22:15:40.196 [main] DEBUG nextflow.Session - Run name: ridiculous_hoover
Jan-28 22:15:40.197 [main] DEBUG nextflow.Session - Executor pool size: 56
Jan-28 22:15:40.208 [main] DEBUG nextflow.file.FilePorter - File porter settings maxRetries=3; maxTransfers=50; pollTimeout=null
Jan-28 22:15:40.216 [main] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'FileTransfer' minSize=10; maxSize=168; workQueue=LinkedBlockingQueue[10000]; allowCoreThreadTimeout=false
Jan-28 22:15:40.254 [main] DEBUG nextflow.cli.CmdRun - 
  Version: 24.10.4 build 5934
  Created: 20-01-2025 16:47 UTC (17:47 CEST)
  System: Linux 6.8.0-51-generic
  Runtime: Groovy 4.0.23 on OpenJDK 64-Bit Server VM 11.0.25+9-post-Ubuntu-1ubuntu122.04
  Encoding: UTF-8 (UTF-8)
  Process: 34911@Dell [127.0.1.1]
  CPUs: 56 - Mem: 125.8 GB (79.3 GB) - Swap: 2 GB (2 GB)
Jan-28 22:15:40.280 [main] DEBUG nextflow.Session - Work-dir: /home/arka/Desktop/Nextflow_projects/BR_nf/work [ext2/ext3]
Jan-28 22:15:40.281 [main] DEBUG nextflow.Session - Script base path does not exist or is not a directory: /home/arka/Desktop/Nextflow_projects/BR_nf/bin
Jan-28 22:15:40.294 [main] DEBUG nextflow.executor.ExecutorFactory - Extension executors providers=[]
Jan-28 22:15:40.309 [main] DEBUG nextflow.Session - Observer factory: DefaultObserverFactory
Jan-28 22:15:40.354 [main] DEBUG nextflow.cache.CacheFactory - Using Nextflow cache factory: nextflow.cache.DefaultCacheFactory
Jan-28 22:15:40.369 [main] DEBUG nextflow.util.CustomThreadPool - Creating default thread pool > poolSize: 57; maxThreads: 1000
Jan-28 22:15:40.499 [main] DEBUG nextflow.Session - Session start
Jan-28 22:15:41.283 [main] DEBUG nextflow.script.ScriptRunner - > Launching execution
Jan-28 22:15:41.438 [main] DEBUG nextflow.script.ScriptRunner - Parsed script files:
  Script_ffb0fc0169112fb4: /home/arka/Desktop/Nextflow_projects/BR_nf/workflow.nf
Jan-28 22:15:41.439 [main] DEBUG nextflow.Session - Session aborted -- Cause: Unknown process directive: `path`

Did you mean of these?
        each
Jan-28 22:15:41.445 [main] DEBUG nextflow.Session - 
Thread[Common-Cleaner,8,InnocuousThreadGroup]
  java.base@11.0.25/java.lang.Object.wait(Native Method)
  java.base@11.0.25/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
  java.base@11.0.25/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:148)
  java.base@11.0.25/java.lang.Thread.run(Thread.java:829)
  java.base@11.0.25/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:161)

Thread[Thread-1,5,main]
  java.base@11.0.25/jdk.internal.misc.Unsafe.park(Native Method)
  java.base@11.0.25/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
  java.base@11.0.25/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)
  java.base@11.0.25/java.util.concurrent.LinkedBlockingDeque.pollFirst(LinkedBlockingDeque.java:513)
  java.base@11.0.25/java.util.concurrent.LinkedBlockingDeque.poll(LinkedBlockingDeque.java:675)
  app//nextflow.util.SimpleAgent.run(SimpleAgent.groovy:89)
  java.base@11.0.25/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  java.base@11.0.25/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  java.base@11.0.25/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  java.base@11.0.25/java.lang.reflect.Method.invoke(Method.java:566)
  app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
  app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
  app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
  app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
  app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
  app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
  app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
  app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
  app//groovy.lang.Closure.call(Closure.java:433)
  app//groovy.lang.Closure.call(Closure.java:412)
  app//groovy.lang.Closure.run(Closure.java:505)
  java.base@11.0.25/java.lang.Thread.run(Thread.java:829)

Thread[AnsiLogObserver,5,main]
  java.base@11.0.25/java.lang.Object.wait(Native Method)
  app//nextflow.trace.AnsiLogObserver.render0(AnsiLogObserver.groovy:185)
  java.base@11.0.25/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  java.base@11.0.25/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  java.base@11.0.25/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  java.base@11.0.25/java.lang.reflect.Method.invoke(Method.java:566)
  app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
  app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
  app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
  app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
  app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
  app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
  app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
  app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
  app//groovy.lang.Closure.call(Closure.java:433)
  app//groovy.lang.Closure.call(Closure.java:412)
  app//groovy.lang.Closure.run(Closure.java:505)
  java.base@11.0.25/java.lang.Thread.run(Thread.java:829)

Thread[main,5,main]
  java.base@11.0.25/java.lang.Thread.dumpThreads(Native Method)
  java.base@11.0.25/java.lang.Thread.getAllStackTraces(Thread.java:1653)
  app//nextflow.util.SysHelper.dumpThreads(SysHelper.groovy:188)
  app//nextflow.Session.abort(Session.groovy:800)
  app//nextflow.script.ScriptRunner.execute(ScriptRunner.groovy:149)
  app//nextflow.cli.CmdRun.run(CmdRun.groovy:376)
  app//nextflow.cli.Launcher.run(Launcher.groovy:503)
  app//nextflow.cli.Launcher.main(Launcher.groovy:658)

Thread[Finalizer,8,system]
  java.base@11.0.25/java.lang.Object.wait(Native Method)
  java.base@11.0.25/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
  java.base@11.0.25/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
  java.base@11.0.25/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)

Thread[Signal Dispatcher,9,system]

Thread[Reference Handler,10,system]
  java.base@11.0.25/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
  java.base@11.0.25/java.lang.ref.Reference.processPendingReferences(Reference.java:241)
  java.base@11.0.25/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)

Thread[process reaper,10,system]
  java.base@11.0.25/jdk.internal.misc.Unsafe.park(Native Method)
  java.base@11.0.25/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
  java.base@11.0.25/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:462)
  java.base@11.0.25/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
  java.base@11.0.25/java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:937)
  java.base@11.0.25/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1053)
  java.base@11.0.25/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
  java.base@11.0.25/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
  java.base@11.0.25/java.lang.Thread.run(Thread.java:829)

Jan-28 22:15:41.455 [main] ERROR nextflow.cli.Launcher - @unknown
nextflow.exception.IllegalDirectiveException: Unknown process directive: `path`

Did you mean of these?
        each
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
	at nextflow.script.ProcessConfig.checkName(ProcessConfig.groovy:239)
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
	at nextflow.script.ProcessConfig.methodMissing(ProcessConfig.groovy:258)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
	at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:924)
	at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1413)
	at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1335)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
	at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:391)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:330)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
	at Script_ffb0fc0169112fb4$_runScript_closure2.doCall(Script_ffb0fc0169112fb4:54)
	at Script_ffb0fc0169112fb4$_runScript_closure2.doCall(Script_ffb0fc0169112fb4)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
	at groovy.lang.Closure.call(Closure.java:433)
	at groovy.lang.Closure.call(Closure.java:412)
	at nextflow.script.ProcessDef.initialize(ProcessDef.groovy:110)
	at nextflow.script.ProcessDef.run(ProcessDef.groovy:168)
	at nextflow.script.BindableDef.invoke_a(BindableDef.groovy:51)
	at nextflow.script.ComponentDef.invoke_o(ComponentDef.groovy:40)
	at nextflow.script.WorkflowBinding.invokeMethod(WorkflowBinding.groovy:103)
	at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:651)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:391)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:330)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
	at Script_ffb0fc0169112fb4$_runScript_closure1$_closure4.doCall(Script_ffb0fc0169112fb4:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
	at groovy.lang.Closure.call(Closure.java:433)
	at groovy.lang.Closure.call(Closure.java:412)
	at nextflow.script.WorkflowDef.run0(WorkflowDef.groovy:204)
	at nextflow.script.WorkflowDef.run(WorkflowDef.groovy:188)
	at nextflow.script.BindableDef.invoke_a(BindableDef.groovy:51)
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
	at nextflow.script.BaseScript.run0(BaseScript.groovy:198)
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
	at nextflow.script.BaseScript.run(BaseScript.groovy:209)
	at nextflow.script.ScriptParser.runScript(ScriptParser.groovy:236)
	at nextflow.script.ScriptRunner.run(ScriptRunner.groovy:243)
	at nextflow.script.ScriptRunner.execute(ScriptRunner.groovy:138)
	at nextflow.cli.CmdRun.run(CmdRun.groovy:376)
	at nextflow.cli.Launcher.run(Launcher.groovy:503)
	at nextflow.cli.Launcher.main(Launcher.groovy:658)

```

* * *

### Additional Details:

1. **Nextflow Version:** 24.10.4
2. **Command Used to Run:**

```bash
nextflow run workflow.nf --input_dir /home/arka/Desktop/Nextflow_projects/BR_nf/input_images --output_dir /home/arka/Desktop/Nextflow_projects/BR_nf/output --diameter_w0 20 --diameter_w1 11.9 --flow_threshold_w0 0.8 --flow_threshold_w1 0.6

```

3. **Container Setup:** I’m using `cellpose_env:latest` and `plotting_env:latest` containers.
4. **Expected Behavior:** The script should execute `processCellpose`, produce outputs (`w0` and `w1`), and pass them to `processPlotting`.

### Issue:

The workflow fails with the error message: `Unknown process directive: path`. I’ve verified that the `path` directive is valid in DSL2. Could there be an issue with how I’m defining outputs or referencing `path` channels?

Any guidance on resolving this issue would be greatly appreciated; I am very new to nextflow and i am still learning.

Thanks in advance for your help! Let me know if further details are required.

Best regards,  
Arka

---

<div class="post-metadata">

**Author:** ![robsyme](https://dub1.discourse-cdn.com/flex013/user_avatar/community.seqera.io/robsyme/32/342_2.png) [@robsyme](https://community.seqera.io/u/robsyme)\
**Post date:** [January 28, 2025, 11:59pm UTC](https://community.seqera.io/t/challenging-nextflow-workflow-need-help-please/1671/2 "2025-01-28T23:59:35Z")

</div>

> [@Arkajyoti\_Sarkar](#):
>
> ```auto
> output:
> tuple(
> path("w0").optional(),
> path("w1").optional()
> )
> 
> ```

I think it’s the way you are specifying optional outputs above. Marking an output as optional is shown as below:

```auto
    output:
        tuple path("w0"), path("w1"), optional: true

```

See [docs here](https://www.nextflow.io/docs/latest/process.html#optional-outputs)

---

<div class="post-metadata">

**Author:** ![mribeirodantas](https://dub1.discourse-cdn.com/flex013/user_avatar/community.seqera.io/mribeirodantas/32/235_2.png) [@mribeirodantas](https://community.seqera.io/u/mribeirodantas)\
**Post date:** [January 29, 2025, 12:04am UTC](https://community.seqera.io/t/challenging-nextflow-workflow-need-help-please/1671/3 "2025-01-29T00:04:23Z")

</div>

Hi @Arkajyoti_Sarkar ! Welcome to Seqera Community Forum 🙂

The first issue I see in your code is in the output block of the `processCellpose` process. See the snippet below:

```auto
    output:
        tuple(
            path("w0").optional(),
            path("w1").optional()
        )

```

I wonder from where you got an example like this. This is definitely not the way we write this block. The correct code follows below:

```auto
   output:                                                                        
        tuple path("w0"), path("w1"), optional: true

```

The first thing to realise is that if a you have a tuple as output, the tuple can be optional, or not. You can’t have part of a tuple being optional, so that’s why the `optional` option goes along the line, after the variables. I’d like to take this opportunity to remind you what it means to have an optional output: Normally, if a specified output is not produced by the task, the task will fail. Setting `optional: true` will cause the task to not fail, and instead emit nothing to the given output channel.

The second issue is that you seem to be confusing the Nextflow language with something else. Maybe Groovy. The following line doesn’t work as you think:

```auto
def (w0, w1) = processCellpose(

```

The `processCellpose` process returns a Nextflow channel and the only way you can handle Nextflow channels is through channel operators. You can’t unpack channels like this just because one or more of its elements is a tuple. You could use a channel operator such as `map` to do something like that, though.

The correct way to run this process and `view` what you want is:

```auto
   ....
   processCellpose(                                                                                                                                         
        params.input_dir,                                                       
        params.output_dir,                                                      
        params.diameter_w0,                                                     
        params.diameter_w1,                                                     
        params.flow_threshold_w0,                                               
        params.flow_threshold_w1                                                
    )                                                                           
                                                                                
    processCellpose.out.view { "w0: $it[0]\nw1: $it[1]" }

    ...

```

I can’t run your code as your instructions to pull these containers do not work, so I changed a bit the code of your process to:

```auto
workflow {                                                                      
    if (!params.input_dir || !params.output_dir || !params.diameter_w0 || !params.diameter_w1 || !params.flow_threshold_w0 || !params.flow_threshold_w1) {
        error "All parameters must be provided."                                
    }                                                                           
                                                                                
    processCellpose(                                                            
        params.input_dir,                                                       
        params.output_dir,                                                      
        params.diameter_w0,                                                     
        params.diameter_w1,                                                     
        params.flow_threshold_w0,                                               
        params.flow_threshold_w1                                                
    )                                                                           
                                                                                
    processCellpose.out.view { "w0: $it[0]\nw1: $it[1]" }
                                                                                
}                                                                               
                                                                                
process processCellpose {                                                       
    container 'cellpose_env:latest'                                             
    input:                                                                      
        val input_dir                                                           
        val output_dir                                                          
        val diameter_w0                                                         
        val diameter_w1                                                         
        val flow_threshold_w0                                                   
        val flow_threshold_w1                                                   
    output:                                                                     
        tuple path("w0"), path("w1"), optional: true                            
                                                                                
    script:                                                                     
    """                                                                         
    touch w0                                                                    
    touch w1                                                                    
  

```

Running like this, you’ll get the following:

 ![CleanShot 2025-01-28 at 21.06.24@2x](https://europe1.discourse-cdn.com/flex013/uploads/seqera/original/2X/1/137d3d455d09fa04c55a26da417f32fccb757372.jpeg)

Oh, one last thing. In your original code, when you view the channel you say something like “w0 channel” and “w1 channel”. This is a misunderstanding ow how it works. The `processCellpose` process has a **single** output channel that consists of elements that individually are tuples. So w0 and w1 are part of a channel element, not channels themselves. I recommend you read the [docs](https://www.nextflow.io/docs/latest/channel.html) and [training materials](https://training.nextflow.io) on Nextflow channels so that this becomes clearer to you, as it’s very important to understand and master other Nextflow concepts.
