I have a custom nextflow plugin that uses TaskRun.getOutputsByType(ValueOutParam) and TaskRun.getOutputsByType(FileOutParam) to get outputs. This seems to be broken after updating to nextflow 26.01.1-edge (using strict syntax and nextflow.preview.types = true). Is that expected? If so, is there a new syntax i should be using? Or should i dig more deeply to see if it’s something else that’s broken?
@bentsherman do you have any ideas about this?
Hi,
Thanks for reporting this. The behaviour you’re seeing is a side effect of the typed processes work that landed in 26.01-edge (nextflow-io/nextflow#6368) and is opted into by nextflow.preview.types = true. It’s not strictly a bug in getOutputsByType, but it does make the v1 OutParam API a dead end for typed processes.
Under the legacy DSL, TaskRun.outputs is a Map<OutParam,Object> keyed by the v1 param classes from nextflow.script.params.* – FileOutParam, ValueOutParam, EnvOutParam, and friends. getOutputsByType(FileOutParam) filters that map by it.key.class.
For typed processes, output declarations are modelled by a parallel set of classes in nextflow.script.params.v2 (e.g. ProcessFileOutput). Resolution runs through TaskOutputResolver and binding through TaskProcessor.bindOutputsV2, which iterates configV2().getOutputs().getParams() and reads task.outputs[param] where param is a typed output, not a FileOutParam.
So under typed processes the keys in task.outputs are never subclasses of FileOutParam/ValueOutParam, and getOutputsByType(FileOutParam) returns an empty map. Internal call sites that still need the v1 view (e.g. the publish helper in TaskProcessor) have been split into V1/V2 variants; plugin code outside the tree hasn’t had that migration applied.
Suggestions
Short-term, you can branch on the process config and read typed outputs via the v2 API:
if (task.processor.config instanceof ProcessConfigV2) {
def cfg = (ProcessConfigV2) task.processor.config
for (def param : cfg.getOutputs().getParams()) {
def value = task.outputs[param]
// inspect param / value here
}
} else {
// existing v1 path
task.getOutputsByType(FileOutParam).each { ... }
}
Caveat: ProcessConfigV2 and the nextflow.script.params.v2 classes are not yet documented as a stable plugin API, so this is best treated as a stop-gap until there’s an explicit plugin-facing replacement. @bentsherman would be the right person to confirm the supported migration path.
Rob has the right idea. Typed processes have a different runtime model for inputs and outputs, so plugins will need to handle legacy/typed processes separately.
You can look at TaskProcessor in the Nextflow runtime to see some examples. I will also update nf-prov at some point to illustrate this.
This will probably remain a rough edge for a while. I might be able to eventually re-unify everything by compiling legacy processes into the typed model under the hood. But for now I think simply handling both cases is your best bet.