Skip to content

Requires does not check if a variable is set #2243

@timrulebosch

Description

@timrulebosch

Description

Requires does not check if a variable is set, it only checks is a variable is "present". As a result, variables which are set to "null/nil" will pass the required check.

Version

3.43.2

Operating system

Linux (WSL)

Experiments Enabled

No response

Example Taskfile

version: '3'
tasks:
  default:
    vars:
      A: null
      B: '{{.B}}'
    env:
      A: '{{.A}}'
      B: '{{.B}}'
      C: '{{.C}}'
    cmds:
      - echo "$A"
      - echo "$B"
      - echo "$C"
    requires:
      #vars: [A, B, C]
      vars: [A, B]

Example output:

$ task
task: [default] echo "$A"

task: [default] echo "$B"

task: [default] echo "$C"

Obviously, none of the variables are set. Swap the comment line on the requires constraint to observe the behavior change.

The related code is here:

_, ok := t.Vars.Get(requiredVar.Name)

... where it is observed that the content of variables is not checked. I have read though the PR for this feature and did not notice any conversation about this scenario. I think the documentation explains the expectation correctly:

List of variable or environment variable names that must be set if this task is to execute and run[period missing]

I appreciate that setting a variable to nil can be considered as being set ... but with how templating works in Task, I think set means set to something other than . For example here there is no difference when A is not set, or set to nil ... the default condition will be taken:

A: '{{.A | default "A"}}'

Activity

added theissue type on May 6, 2025
timrulebosch

timrulebosch commented on Jun 4, 2025

@timrulebosch
Author

The fundamental problem behind this is that a variable has no nil representation. This is apparently because the tempting system will raise errors in such cases ... and therefore any nil (null in yaml) value will be set to an empty string. Ok.

I've developed a fix for that, i.e. the requires feature checks for a "nil" value. That works ... however it introduces a conflict to #1962 and #1962 and #2033 ... which moves the requires check before the task is compiled. Which means tasks like this fail with the fix I developed:

  validation-var-dynamic:
    vars:
      FOO:
        sh: echo "one" ***** not evaluated until _after_ a task is compiled.
    requires:
      vars:
        - name: FOO
          enum: ['one', 'two']

@vmaerten Do you have any thoughts? As far as I can see, compiling a task is ... doing much more than tempting variables. And so that causes cases like:

require-before-compile:
    requires:
      vars: [ MY_VAR ]
    cmd: |
      {{range .MY_VAR | splitList " " }}
        echo {{.}}
      {{end}}

to fail (if task compile is moved before requires checks).

Ideally I would "detect" the sh portion, or compile variables only before doing the requires check.

timrulebosch

timrulebosch commented on Jun 5, 2025

@timrulebosch
Author

I've figured out what was happening and updated the related PR.

linked a pull request that will close this issue on Jul 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @vmaerten@timrulebosch@task-bot

      Issue actions

        Requires does not check if a variable is set · Issue #2243 · go-task/task