Bug report
Summary
When workflow.failOnIgnore = true and a task fails under errorStrategy 'ignore', the nextflow process correctly exits with code 1, but workflow.success is still true and workflow.exitStatus is 0.
Because workflow.success / workflow.exitStatus are what the workflow.onComplete handler, the built-in email notification, and downstream trace/reporting integrations consume, those all report the run as successful even though the CLI exit code is a failure. Anything that keys off workflow.onComplete (dashboards, notifications, monitoring) sees a green run.
This is the same class of bug as #6962 (AgentLogObserver printing [SUCCESS] on a failed run), which was fixed by switching that observer to session.isSuccess(). WorkflowMetadata.success was not updated and still ignores failOnIgnore. It's also the underlying reason behind the confusion in #6297 — the reporter there only ever checked the exit code, so "upgrading fixed it" masked the fact that workflow.success is still wrong.
Minimal reproducible example
main.nf:
process FAILME {
errorStrategy 'ignore'
script:
"""
echo boom; exit 1
"""
}
workflow {
FAILME()
}
nextflow.config:
workflow {
failOnIgnore = true
onComplete = {
println "onComplete -> workflow.success=${workflow.success} workflow.exitStatus=${workflow.exitStatus}"
}
}
Run and capture the process exit code:
nextflow run main.nf ; echo "nextflow exit code = $?"
Actual behaviour
onComplete -> workflow.success=true workflow.exitStatus=0
nextflow exit code = 1
workflow.success is true and workflow.exitStatus is 0, contradicting the process exit code of 1.
Expected behaviour
When failOnIgnore triggers a failure, workflow.success should be false and workflow.exitStatus should be non-zero, consistent with the CLI exit code, so onComplete/email/reporting see the run as failed.
Root cause
Two separate success computations disagree:
Session.isSuccess() — !aborted && !cancelled && !failOnIgnore — drives the CLI exit code (via ScriptRunner). Correctly returns failure.
WorkflowMetadata.invokeOnComplete() sets this.success = !(session.aborted || session.cancelled), which omits failOnIgnore. Since failOnIgnore sets no session.fault, setErrorAttributes() falls through to the else branch and assigns exitStatus = 0.
Suggested fix (mirrors #6962): base WorkflowMetadata.success on session.isSuccess() and set a non-zero exitStatus on the failOnIgnore path.
Environment
- Nextflow version: 26.04.4 (also reproducible on the 25.04 line)
- Java: 17
- OS: macOS
- Executor: local (not executor-specific — the divergence is in
WorkflowMetadata)
Bug report
Summary
When
workflow.failOnIgnore = trueand a task fails undererrorStrategy 'ignore', thenextflowprocess correctly exits with code 1, butworkflow.successis stilltrueandworkflow.exitStatusis0.Because
workflow.success/workflow.exitStatusare what theworkflow.onCompletehandler, the built-in email notification, and downstream trace/reporting integrations consume, those all report the run as successful even though the CLI exit code is a failure. Anything that keys offworkflow.onComplete(dashboards, notifications, monitoring) sees a green run.This is the same class of bug as #6962 (
AgentLogObserverprinting[SUCCESS]on a failed run), which was fixed by switching that observer tosession.isSuccess().WorkflowMetadata.successwas not updated and still ignoresfailOnIgnore. It's also the underlying reason behind the confusion in #6297 — the reporter there only ever checked the exit code, so "upgrading fixed it" masked the fact thatworkflow.successis still wrong.Minimal reproducible example
main.nf:nextflow.config:workflow { failOnIgnore = true onComplete = { println "onComplete -> workflow.success=${workflow.success} workflow.exitStatus=${workflow.exitStatus}" } }Run and capture the process exit code:
Actual behaviour
workflow.successistrueandworkflow.exitStatusis0, contradicting the process exit code of1.Expected behaviour
When
failOnIgnoretriggers a failure,workflow.successshould befalseandworkflow.exitStatusshould be non-zero, consistent with the CLI exit code, soonComplete/email/reporting see the run as failed.Root cause
Two separate success computations disagree:
Session.isSuccess()—!aborted && !cancelled && !failOnIgnore— drives the CLI exit code (viaScriptRunner). Correctly returns failure.WorkflowMetadata.invokeOnComplete()setsthis.success = !(session.aborted || session.cancelled), which omitsfailOnIgnore. SincefailOnIgnoresets nosession.fault,setErrorAttributes()falls through to theelsebranch and assignsexitStatus = 0.Suggested fix (mirrors #6962): base
WorkflowMetadata.successonsession.isSuccess()and set a non-zeroexitStatuson thefailOnIgnorepath.Environment
WorkflowMetadata)