argoproj / argoproj/argo-workflows

Unable to set / access global output using DAG workflow and `onExit` handler

Open
#14,767 3 comments 7 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
17k
Forks
3.7k
Avg merge
1d 20h
Merged PRs (30d)
138

Description

### Pre-requisites

- [x] I have double-checked my configuration
- [x] I have tested with the `:latest` image tag (i.e. `quay.io/argoproj/workflow-controller:latest`) and can confirm the issue still exists on `:latest`. If not, I have explained why, **in detail**, in my description below.
- [x] I have searched existing issues and could not find a match for this bug
- [ ] I'd like to contribute the fix myself (see [contributing guide](https://github.com/argoproj/argo-workflows/blob/main/docs/CONTRIBUTING.md))

### What happened? What did you expect to happen?

I'm trying to create a `WorkflowTemplate` that on a failure condition will restore some workloads. I use some task templates to scale workloads down, and scale workloads up. There seems to be no way to access the outputs from DAG tasks in an `onExit` handler. There does seem to be a workaround where we could wrap a task template in another template, but that is not ideal and would need a template for every task. I think there should be a more simple pattern to support this.

### Version(s)

v3.6.10

### Paste a minimal workflow that reproduces the issue. We must be able to run the workflow; don't enter a workflow that uses private images.

```YAML
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: dag-template-exit-outputs
spec:
entrypoint: main
onExit: exit-handler
templates:
- name: main
dag:
tasks:
- name: scale-down-foo
template: scale-down
arguments:
parameters:
- name: workload
value: "deployment/foo"
- name: namespace
value: "{{workflow.parameters.namespace}}"
- name: scale-down-bar
template: scale-down
arguments:
parameters:
- name: workload
value: "deployment/bar"
- name: namespace
value: "{{workflow.parameters.namespace}}"

outputs:
parameters:
- name: foo-replicas
value: "{{tasks.scale-down-foo.outputs.parameters.replicas}}"
globalName: foo-replicas
- name: bar-replicas
value: "{{tasks.scale-down-bar.outputs.parameters.replicas}}"
globalName: bar-replicas

- name: exit-handler
steps:
- - name: scale-up-foo
template: scale-up
when: "{{workflow.outputs.parameters.foo-replicas}} != '' && {{workflow.outputs.parameters.foo-replicas}} > 0"
arguments:
parameters:
- name: workload
value: "deployment/foo"
- name: replicas
value: "{{workflow.outputs.parameters.foo-replicas}}"
- name: namespace
value: "{{workflow.parameters.namespace}}"
- name: scale-up-bar
template: scale-up
when: "{{workflow.outputs.parameters.bar-replicas}} != '' && {{workflow.outputs.parameters.bar-replicas}} > 0"
arguments:
parameters:
- name: workload
value: "deployment/bar"
- name: replicas
value: "{{workflow.outputs.parameters.bar-replicas}}"
- name: namespace
value: "{{workflow.parameters.namespace}}"

- name: scale-down
inputs:
parameters:
- name: workload
- name: namespace
outputs:
parameters:
- name: replicas
valueFrom:
path: /tmp/replicas.txt
script:
image: bitnami/kubectl:latest
command: [ sh ]
env:
- name: NAMESPACE
value: "{{inputs.parameters.namespace}}"
- name: WORKLOAD
value: "{{inputs.parameters.workload}}"
source: |
# scale down stuff

- name: scale-up
inputs:
parameters:
- name: workload
- name: replicas
- name: namespace
script:
image: bitnami/kubectl:latest
command: [ sh ]
source: |
# scale up stuff
```

### Logs from the workflow controller

```text
There are no controller logs created.

The workflows server logs show this:

time="2025-08-16T03:15:29.120Z" level=info msg="finished unary call with code InvalidArgument" error="rpc error: code = InvalidArgument desc = templates.exit-handler.steps failed to resolve {{workflow.outputs.parameters.foo-replicas}}" grpc.code=InvalidArgument grpc.method=CreateWorkflowTemplate grpc.service=workflowtemplate.WorkflowTemplateService grpc.start_time="2025-08-16T03:15:29Z" grpc.time_ms=1.165 span.kind=server system=grpc

The UI shows this:

Bad Request: templates.exit-handler.steps failed to resolve {{workflow.outputs.parameters.foo-replicas}}
```

### Logs from in your workflow's wait container

```text
n/a
```

Contributor guide

Open the contributing guide

Research direction

Start with the minimal WorkflowTemplate in the issue and reproduce the workflows server validation error when resolving workflow.outputs.parameters in the onExit steps. Trace how DAG outputs with globalName are validated and made available to exit handlers. Done means the template is accepted and the exit handler can resolve foo-replicas and bar-replicas for its conditions and arguments.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes
Domain
backend, distributed-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.