Evangelos Karatzas
09/03/2026, 9:39 AMpublishDir = [
[
path: { "${params.outdir}/remove_redundancy/merge_families/full_msa/raw/mgnifam/${meta.id}/" },
mode: params.publish_dir_mode,
pattern: "*/full_msa/*",
saveAs: { filename -> filename.tokenize('/').last() }
],
[
path: { "${params.outdir}/remove_redundancy/merge_families/hmm/raw/mgnifam/${meta.id}/" },
mode: params.publish_dir_mode,
pattern: "*/hmm/*",
saveAs: { filename -> filename.tokenize('/').last() }
],
[
path: { "${params.outdir}/remove_redundancy/merge_families/generate_families_iteratively/${meta.id}/" },
mode: params.publish_dir_mode,
enabled: params.save_iterative_family_metadata,
pattern: "*/*.*"
]
]
Is this wanted behaviour or a bug?
What is the suggested way of writing these now? I don't like what the bots are proposing and cannot see any alternative:
publishDir = [
path: { "${params.outdir}/remove_redundancy/merge_families" },
mode: params.publish_dir_mode,
saveAs: { filename ->
def parts = filename.tokenize('/')
if (parts.size() == 3 && parts[1] == 'full_msa') { return "full_msa/raw/mgnifam/${meta.id}/${parts[2]}" }
if (parts.size() == 3 && parts[1] == 'hmm') { return "hmm/raw/mgnifam/${meta.id}/${parts[2]}" }
if (!params.save_iterative_family_metadata) { return null }
if (parts.size() == 2 && parts[1].contains('.')) { return "generate_families_iteratively/${meta.id}/${filename}" }
return null
}
]Phil Ewels
09/03/2026, 9:41 AMEvangelos Karatzas
09/03/2026, 9:42 AMPhil Ewels
09/03/2026, 9:42 AMEvangelos Karatzas
09/03/2026, 9:43 AMEvangelos Karatzas
09/03/2026, 9:44 AMconfig -flat changed to config -o json. By Claude:
-flat prints dotted key/value pairs and never serializes closures. -o json runs Groovy's JsonOutput over the config tree — and that's where closures nested inside list elements (never wrapped as ConfigClosurePlaceholder, unlike map values) get invoked against a JsonDelegate, giving No such variable: meta.Niklas Schandry
09/03/2026, 9:46 AMpattern: before on the filenames instead of tokenizing it?Mahesh Binzer-Panchal
09/03/2026, 9:46 AMEvangelos Karatzas
09/03/2026, 9:46 AMSo the list-of-maps was always latently unserializable; nothing ever asked for JSON until 4.1.0. Nextflow's asymmetric closure wrapping is arguably the real bug — worth an issue on nextflow-io/nextflow if you want it fixed at the source rather than worked around in every pipeline.Evangelos Karatzas
09/03/2026, 9:47 AMJim Downie
09/03/2026, 9:50 AMEvangelos Karatzas
09/03/2026, 9:50 AMEvangelos Karatzas
09/03/2026, 9:51 AMEvangelos Karatzas
09/03/2026, 9:52 AMJim Downie
09/03/2026, 9:52 AMsaveAs: { filename -> filename?.tokenize('/') }Jim Downie
09/03/2026, 9:52 AMJim Downie
09/03/2026, 9:54 AMEvangelos Karatzas
09/03/2026, 9:59 AMfilename? 😞Jim Downie
09/03/2026, 10:00 AMfilename is null:
saveAs: { filename -> filename?.tokenize('/')?.last() }Evangelos Karatzas
09/03/2026, 10:32 AMpublishDir = [
[
path: "${params.outdir}/full_msa/raw/mgnifam",
mode: params.publish_dir_mode,
pattern: "*/full_msa/*",
saveAs: { filename -> filename ? "${meta.id}/${filename.tokenize('/').last()}" : null }
],
[
path: "${params.outdir}/hmm/raw/mgnifam",
mode: params.publish_dir_mode,
pattern: "*/hmm/*",
saveAs: { filename -> filename ? "${meta.id}/${filename.tokenize('/').last()}" : null }
],
[
path: "${params.outdir}/generate_families_iteratively",
mode: params.publish_dir_mode,
enabled: params.save_iterative_family_metadata,
pattern: "*/*.*",
saveAs: { filename -> filename ? "${meta.id}/${filename}" : null }
],
[
path: "${params.outdir}/generate_families_iteratively",
mode: params.publish_dir_mode,
enabled: params.save_iterative_family_metadata,
pattern: "*/rf/*",
saveAs: { filename -> filename ? "${meta.id}/${filename}" : null }
]
]
Thanks again Jim!