Skip to content

Fix PREP/UPDATE/SUBMIT_SUBMISSION for cloud executors (val→path staging, setup_logging, optional log outputs) - #361

Open
smanda4 wants to merge 5 commits into
CDCgov:feature/measles-vadrfrom
azpathogens:feature/measles-vadr
Open

smanda4 wants to merge 5 commits into
CDCgov:feature/measles-vadrfrom
azpathogens:feature/measles-vadr

Conversation

@smanda4

@smanda4 smanda4 commented Jul 7, 2026

Copy link
Copy Markdown

Description

Please Describe the Bug(s) Fixed and/or the Feature(s) Added:

Three related fixes for tostadas on cloud executors (validated on Google Batch via Seqera Platform; applies to any executor with a URI-shaped workDir). The original scope was the FileNotFoundError in PREP_SUBMISSION / UPDATE_SUBMISSION; two additional bugs surfaced during end-to-end validation and are fixed alongside.

Fix 1: PREP_SUBMISSION and UPDATE_SUBMISSION — val vs path staging

PREP_SUBMISSION and UPDATE_SUBMISSION reference file paths through a val-typed meta/samples map (${meta.batch_tsv}, ${sample.fasta}, etc.). Because those are val inputs and not path inputs, Nextflow doesn't stage the referenced files into the task container. On cloud executors the paths resolve to raw workDir URIs (/tostadas-work/<hash>/...) that don't exist inside the container, and both modules fail before the submission scripts ever run.

Example failure on a cloud executor:

submission_prep.py --metadata_file /tostadas-work/<task-hash>/genbank/batch_1.tsv ...
FileNotFoundError: '/tostadas-work/<task-hash>/genbank/batch_1.tsv'

(where /tostadas-work/ is the workDir set in nextflow.config for the cloud executor)

Fix: lift each per-sample file type out of the meta/samples map into an explicit path input list. Nextflow then stages each list into a per-type subdirectory in the work dir, and the script walks samples in the same order the upstream workflow emitted them, popping the next entry from each file iterator whenever the sample declares that key. Same pattern used in 915d2b3 for submission_config staging in METADATA_VALIDATION. See commits febfe53, 2c2fe1b, c9980bb.

Fix 2: setup_logging silently no-ops when handlers pre-exist

submission_helper.py::setup_logging was guarded by if not logging.getLogger().handlers: and silently returned without configuring anything when handlers already existed. Inside the staphb/tostadas container an earlier import pre-registers a root-logger handler, so FileHandler was never attached and the *.log files that the Nextflow modules declare as outputs (prep_submission.log, update_submission.log, submission.log) were never actually written.

Fix: drop the guard and add force=True to logging.basicConfig so the root logger is unconditionally reconfigured. See commit 10e6544.

Fix 3: Drop optional log-file output declarations in PREP/UPDATE/SUBMIT_SUBMISSION

Even with Fix 2 applied, cloud-executor runs still failed with mv: cannot stat '.../*.log': No such file or directory. On the Google Batch executor, optional: true on path output declarations isn't fully respected during output staging — the staging step attempts mv on the declared file unconditionally and fails the task when the file isn't there.

Fix: remove the individual submission_log output declarations from prep_submission/main.nf, update_submission/main.nf, and submit_submission/main.nf. The catch-all path("${meta.batch_id}") directory output still captures the log file when produced, so downstream consumers don't lose it in successful runs. fetch_reports/main.nf was left as-is because it uses optional: false (log file is expected/required per the schema); with Fix 2, the log file should always exist by that point. See commit 383447d.

Drive-by fix

While in PREP_SUBMISSION I noticed the sample_args builder was checking sample.get("nnp") but referencing sample.nanopore. Upstream workflows populate the "nanopore" key, so the "nnp" check was always false and nanopore samples were silently omitted from sample_args. Fixed to check the correct "nanopore" key.

Files touched

Fix 1 (val/path staging):

  • modules/local/prep_submission/main.nf — tuple input now includes staged batch_tsv plus five path lists (fastas, gffs, fq1s, fq2s, nnps); script uses iterators to zip samples with staged files
  • modules/local/update_submission/main.nf — tuple input includes staged batch_tsv; script references $batch_tsv
  • subworkflows/local/submission.nf — updated take comment
  • workflows/genbank.nfsubmission_batch_ch now emits a 9-item tuple
  • workflows/biosample_and_sra.nf — same shape (fq1/fq2/nnp populated instead of fasta/gff)
  • workflows/biosample_update.nfrebatch_ch tuple includes tsv_file

Fix 2 (setup_logging force=True):

  • bin/submission_helper.py — drop guard, add force=True

Fix 3 (drop optional log outputs):

  • modules/local/prep_submission/main.nf
  • modules/local/update_submission/main.nf
  • modules/local/submit_submission/main.nf

Checklist

Go Through Checklist Below and Place A ✔️ (X Inside the Box) if Completed

General Checks

  • Have you run appropriate tests (unit/integration/end-to-end) to check logic across run environments (Conda/Docker/Singularity on Scicomp/AWS/NF Tower/Local)?

    Validated end-to-end on Docker + Google Batch (via Seqera Platform) for the genbank workflow with all three fixes applied:

    • Single-sample measles VADR dry-run (AF266288, a public GenBank accession)
    • 8/8 pipeline tasks succeeded (CREATE_BATCH_TSVS → GENBANK_VALIDATION → VADR_MODEL_SETUP → VADR_TRIM → VADR_ANNOTATION → VADR_POST_CLEANUP → PREP_SUBMISSION → SUBMIT_SUBMISSION)
    • Output artifacts confirmed: .sqn, .tbl, .zip, VADR reports
    • Generated .sqn opens with a proper Seq-submit ::= { ASN.1 header and populated contact/affiliation blocks

    Did not test Conda / Singularity / Scicomp / AWS / NF Tower / Local execution paths, nor the biosample_and_sra or biosample_update workflows (no biosample test data available in the environment). Those workflows use the same channel-wiring pattern as genbank and the fixes were applied identically, so they should work, but happy to gate on additional testing if the reviewer wants.

  • Have you conducted proper linting procedures?

    • Block comments added at each change explaining the WHY (why files need to be lifted out of val, why iterator coercion is needed, why the setup_logging guard is dropped, why the log outputs are removed)
    • Variable naming matches existing tostadas conventions
    • No Python formatting churn beyond the setup_logging change
  • Have you updated existing documentation (README.md, etc.) or created new ones within docs?

    Bug fixes, not new features. Existing README doesn't need changes. Happy to add a "cloud executor support" note if the reviewer prefers.

CDC Checks

  • Did you check for sensitive data, and remove any?

    Confirmed: no infrastructure identifiers, credentials, or environment-specific paths in the diff or PR body. Comments use generic examples.

  • If you added or modified HTML, did you check that it was 508 compliant?

    N/A — no HTML in this PR.

Are additional approvals needed for this change? If so, please mention them below:

Not that I'm aware of, but please flag if there are.

Are there potential vulnerabilities or licensing issues with any new dependencies introduced? If so, please mention them below:

No new dependencies introduced.

smanda4 added 3 commits July 7, 2026 10:54
…s work

PREP_SUBMISSION and UPDATE_SUBMISSION referenced file paths via a val-typed
meta/samples map (${meta.batch_tsv}, ${sample.fasta}, ${sample.gff},
${sample.fq1}, ${sample.fq2}, ${sample.nanopore}). Nextflow doesn't stage
files referenced from inside a val input, so on cloud executors like
Google Batch the paths resolve to raw workDir URIs
(/tostadas-work/<hash>/...) that don't exist inside the container. Both
modules fail with FileNotFoundError before running the submission scripts.

Fix: lift each per-sample file type out of the meta/samples map into an
explicit path input list. Nextflow stages each list into a per-type
subdirectory in the work dir; the script walks samples in the same order
as the upstream workflow emitted them and pops the next entry from each
file iterator when the sample declares that key. Same fix pattern as
915d2b3 for METADATA_VALIDATION's submission_config.

Also fixed a pre-existing bug where PREP_SUBMISSION checked
sample.get("nnp") but referenced sample.nanopore; the correct key is
"nanopore", so the previous "nnp" check was always false and nanopore
samples were silently omitted from sample_args.

Files:
  modules/local/prep_submission/main.nf     - tuple input now includes
    staged batch_tsv + 5 path lists (fastas, gffs, fq1s, fq2s, nnps);
    script uses iterators to zip samples with staged files
  modules/local/update_submission/main.nf   - tuple input includes
    staged batch_tsv; script references \$batch_tsv
  subworkflows/local/submission.nf          - updated take comment
  workflows/genbank.nf                      - submission_batch_ch emits
    9-item tuple (fasta/gff populated; fq1/fq2/nnp empty)
  workflows/biosample_and_sra.nf            - same shape (fq1/fq2/nnp
    populated; fasta/gff empty)
  workflows/biosample_update.nf             - rebatch_ch tuple now
    includes tsv_file

Fixes cloud-executor blocker for genbank, biosample_and_sra, and
biosample_update workflows.
Nextflow binds a `path` input to a single Path object when it receives
one file and to a List when it receives multiple. Calling `.iterator()`
directly on a Path iterates its name segments instead of the file, so a
single-item `fastas` came out as "fastas" (the staging directory name)
and submission_prep.py hit `IsADirectoryError: 'gffs'` when it tried to
open the value as a file. Wrap each input in an `asList` helper before
iterating; empty lists stay empty and are never dereferenced because
the sample map doesn't declare the corresponding key.
Reword the fix comments to avoid executor-specific and test-data-specific
mentions:
- Drop "on Google Batch" phrasing where the point applies to any cloud
  executor with a URI-shaped workDir
- Replace a test-data-specific filename (AF266288_cleaned.fsa) with
  "the basename" so the example reads generically

No functional change; comment-only cleanup.
smanda4 added a commit to azpathogens/apgap-notebooks that referenced this pull request Jul 8, 2026
The smanda4/tostadas fork was transferred to azpathogens/tostadas so it
lives in the org rather than a personal account. GitHub redirects the
old URL, but users are better served by the canonical org URL. Also
adds a direct link to CDCgov/tostadas#361 (the pending upstream PR) in
the intro markdown and parameter cell comment.
@smanda4
smanda4 force-pushed the feature/measles-vadr branch from 391a9c9 to 3736d56 Compare July 22, 2026 22:54
smanda4 added 2 commits July 23, 2026 12:37
The guard 'if not logging.getLogger().handlers' silently no-ops if
handlers exist. In staphb/tostadas an earlier import pre-registers
a handler, so FileHandler was never attached and the *.log files
declared as Nextflow module outputs never got created, causing
PREP_SUBMISSION and UPDATE_SUBMISSION to fail on cloud executors
during output staging. Use force=True so basicConfig reconfigures
the root logger unconditionally.
…cloud executors

Nextflow's Google Batch executor does not fully respect
`optional: true` on path output declarations: during staging it
still attempts `mv` on the declared file even when it does not
exist, failing the task with:

    mv: cannot stat '.../prep_submission.log': No such file or directory
    mv: cannot stat '.../update_submission.log': No such file or directory
    mv: cannot stat '.../submission.log':      No such file or directory

Reproducible on GCP Batch runs of the measles VADR genbank dry-run
where the Python submission scripts (submission_prep.py,
submission_update.py, submission.py) don't reliably create their
log file (setup_logging can silently no-op inside the staphb
container's runtime — separately addressed by adding `force=True`
to `logging.basicConfig`).

Removing the individual log-file output declarations eliminates the
staging attempt entirely. The log file (when produced) is still
captured by the catch-all `path("${meta.batch_id}")` directory
output, so downstream consumers keep receiving it in successful
runs.

Validated end-to-end on Seqera Platform + GCP Batch: 8/8 tasks
succeeded on measles VADR genbank dry-run.
@smanda4
smanda4 force-pushed the feature/measles-vadr branch from fea5cdc to 383447d Compare July 23, 2026 19:40
@smanda4 smanda4 changed the title fix PREP_SUBMISSION and UPDATE_SUBMISSION to stage batch_tsv and sample files as process inputs Fix PREP/UPDATE/SUBMIT_SUBMISSION for cloud executors (val→path staging, setup_logging, optional log outputs) Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant