Skip to content

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

@mbrancato

Description

@mbrancato

Pre-requisites

  • I have double-checked my configuration
  • 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.
  • 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)

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.

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

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

n/a

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions