Skip to content

Seqera Platform begin request contains invalid JSON when a param value fails to serialize #7771

Description

@pinin4fjords

Bug report

Expected behavior and actual behavior

TowerJsonGenerator should always produce valid JSON. When a value fails to serialize, it logs a warning and writes the field name but no value, so the request body is invalid and the next field follows directly: "params":{"x":},"id":....

This is separate from #7758/#7759, which fixed typed Channel/Value params through ParamsMap.toPlainMap(). A legacy script that assigns a dataflow value to a param still hits it.

Steps to reproduce the problem

params.x = channel.value(1)
workflow { println 'done' }
nextflow run main.nf -with-tower <endpoint>

channel.of(1).collect() and channel.of(1).toList() behave the same. channel.of(1) and channel.fromPath(..) are not affected.

Program output

WARN: Unable to serialize key=workflow.params.x; value=DataflowVariable(value=null); type=groovyx.gpars.dataflow.DataflowVariable -- Cause: Cannot invoke "groovyx.gpars.serial.SerialContext.add(groovyx.gpars.serial.SerialHandle)" because "this.context" is null

Captured begin payload (invalid JSON):

"params":{"x":},"id":"abc123",...

Environment

  • Nextflow version: 26.09.2-edge (master 9563c73)
  • Java version: 21.0.10
  • Operating system: macOS (aarch64)
  • Bash version: zsh 5.9

Additional context

The cause is the catch block in TowerJsonGenerator.writeObject (plugins/nf-tower/src/main/io/seqera/tower/plugin/TowerJsonGenerator.groovy), which writes no value after the key has been emitted.

Separately, params.x = channel.empty() blocks the main thread in DataflowQueue.getVal while the generator reads the channel's properties. That is a different failure and is not covered here.

Activity

  1. bentsherman commented on Oct 7, 2026

    @bentsherman
    Member

    Is that the only motivating example? Setting a legacy param to a channel? If so then I'm not sure it's worth trying to guard, considering that no one ever does this

  2. pinin4fjords commented on Oct 7, 2026

    @pinin4fjords
    ContributorAuthor

    No, that's the only one I found. I don't have a report of anyone doing it in a real pipeline. I hit it by testing legacy params with dataflow values (channel.value(1), .collect(), .toList()); the typed case was the real-world one and #7759 covers it.

    The case for the guard is that the generator is a catch-and-continue that currently emits an invalid document whenever any value throws, and Platform then drops the whole begin event. Writing null is one line and makes that failure local to one field. If you'd rather not carry it for a case nobody hits, I'm happy to close this and the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions