Argo: nested template outputs produce runtime error: invalid memory address or nil pointer dereference

Created on 8 Dec 2019  ·  3Comments  ·  Source: argoproj/argo

Is this a BUG REPORT or FEATURE REQUEST?:
BUG

What happened:

Name:                dag-nested-outputs-bug-n2bn6
Namespace:           argo
ServiceAccount:      default
Status:              Error
Message:             runtime error: invalid memory address or nil pointer dereference
Created:             Sun Dec 08 09:44:24 +0100 (6 seconds ago)
Started:             Sun Dec 08 09:44:24 +0100 (6 seconds ago)
Finished:            Sun Dec 08 09:44:32 +0100 (1 second from now)
Duration:            8 seconds

STEP                                       PODNAME                                  DURATION  MESSAGE
 ● dag-nested-outputs-bug-n2bn6 (diamond)                                                     
 └-● A (check)                                                                                
   ├-✔ A (echo)                            dag-nested-outputs-bug-n2bn6-4101124854  3s        
   └-✔ B (echo)                            dag-nested-outputs-bug-n2bn6-4084347235  3s

What you expected to happen:
I expect to be able to pass outputs even from templates that contain steps/tasks.

How to reproduce it (as minimally and precisely as possible):


Workflow to reproduce

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: dag-nested-outputs-bug-
spec:
  entrypoint: diamond
  templates:
  - name: diamond
    dag:
      tasks:
      - name: A
        template: check
        arguments:
          parameters: [{name: message, value: checkA}]
      - name: B
        dependencies: [A]
        template: echo
        arguments:
          parameters:
          - name: message
            value: >-
              I don't even need to access the previous output for this Workflow to fail.
  - name: check
    inputs:
      parameters:
      - name: message
    outputs:
      parameters:
      - name: status
        value: '0'
        # alternatively (both fail):
        # value: this would normally get outputs from {{tasks.B.status}} for example
    dag:
      tasks:
      - name: A
        template: echo
        arguments:
          parameters: [{name: message, value: "{{inputs.parameters.message}}"}]
      - name: B
        dependencies: [A]
        template: echo
        arguments:
          parameters: [{name: message, value: "{{inputs.parameters.message}}"}]
  - name: echo
    inputs:
      parameters:
      - name: message
    container:
      image: alpine:3.7
      command: [echo, "{{inputs.parameters.message}}"]


Environment:

  • Argo version:
$ argo version

argo: v2.4.1
  BuildDate: 2019-10-08T23:14:59Z
  GitCommit: d7f099992d8cf93c280df2ed38a0b9a1b2614e56
  GitTreeState: clean
  GitTag: v2.4.1
  GoVersion: go1.11.5
  Compiler: gc
  Platform: linux/amd64
bug

Most helpful comment

I don't think you're supposed to use the outputs.parameters.value field directly. That field gets filled in based on the contents of valueFrom precisely on the function that causes the panic in this issue:
https://github.com/argoproj/argo/blob/b3d458504b319b3b02b82a872a5e13c59cb3128f/workflow/controller/operator.go#L1595

Instead, you should use valueFrom and specify where you want the value of the output to get filled from.

Here is an example using your sample workflow:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: dag-nested-outputs-bug-
spec:
  entrypoint: diamond
  templates:
  - name: diamond
    dag:
      tasks:
      - name: A
        template: check
        arguments:
          parameters: [{name: message, value: checkA}]
      - name: B
        dependencies: [A]
        template: echo
        arguments:
          parameters:
          - name: message
            value: "Here!"
  - name: check
    inputs:
      parameters:
      - name: message
    outputs:
      parameters:
      - name: status
        valueFrom: # <-- Notice valueFrom
          parameter: "{{tasks.A.outputs.parameters.out-parameter}}"
    dag:
      tasks:
      - name: A
        template: echo
        arguments:
          parameters: [{name: message, value: "{{inputs.parameters.message}}"}]
      - name: B1
        dependencies: [A]
        template: echo
        arguments:
          parameters: [{name: message, value: "{{inputs.parameters.message}}"}]
  - name: echo
    inputs:
      parameters:
      - name: message
    container:
      image: alpine:3.7
      command: [sh, -c]
      args: ["echo {{inputs.parameters.message}} > /tmp/my-output-parameter.txt"]
    outputs:
      parameters:
      - name: out-parameter
        valueFrom:
          path: /tmp/my-output-parameter.txt

All 3 comments

I don't think you're supposed to use the outputs.parameters.value field directly. That field gets filled in based on the contents of valueFrom precisely on the function that causes the panic in this issue:
https://github.com/argoproj/argo/blob/b3d458504b319b3b02b82a872a5e13c59cb3128f/workflow/controller/operator.go#L1595

Instead, you should use valueFrom and specify where you want the value of the output to get filled from.

Here is an example using your sample workflow:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: dag-nested-outputs-bug-
spec:
  entrypoint: diamond
  templates:
  - name: diamond
    dag:
      tasks:
      - name: A
        template: check
        arguments:
          parameters: [{name: message, value: checkA}]
      - name: B
        dependencies: [A]
        template: echo
        arguments:
          parameters:
          - name: message
            value: "Here!"
  - name: check
    inputs:
      parameters:
      - name: message
    outputs:
      parameters:
      - name: status
        valueFrom: # <-- Notice valueFrom
          parameter: "{{tasks.A.outputs.parameters.out-parameter}}"
    dag:
      tasks:
      - name: A
        template: echo
        arguments:
          parameters: [{name: message, value: "{{inputs.parameters.message}}"}]
      - name: B1
        dependencies: [A]
        template: echo
        arguments:
          parameters: [{name: message, value: "{{inputs.parameters.message}}"}]
  - name: echo
    inputs:
      parameters:
      - name: message
    container:
      image: alpine:3.7
      command: [sh, -c]
      args: ["echo {{inputs.parameters.message}} > /tmp/my-output-parameter.txt"]
    outputs:
      parameters:
      - name: out-parameter
        valueFrom:
          path: /tmp/my-output-parameter.txt

Will be closing this for now but feel free to reopen if necessary

Ah, I see, darn it! Thanks a lot!

Was this page helpful?
0 / 5 - 0 ratings