Skip to content

Regression in v3.49.0: Global sh: variables resolve to empty string in included Taskfiles #2720

Description

@JonZeolla

Description

After upgrading from Task v3.48.0 to v3.49.0, global variables defined with sh: no longer resolve correctly when a Taskfile has includes:. The sh: variable resolves to an empty string, causing downstream variables that reference it via templating to produce incorrect values.

This regression was introduced by #2632 (commit 2cdd7d3), which shipped in v3.49.0.

Root Cause

The added line in compiler.go (line 118):

c.TaskfileVars = templater.ReplaceVars(c.TaskfileVars, &templater.Cache{Vars: result})

This mutates c.TaskfileVars after sh: dynamic variables have already been resolved by rangeFunc (lines 112-116), destroying their cached results.

Step-by-step breakdown:

  1. Lines 112-116 (rangeFunc): Iterates c.TaskfileVars. For sh: vars like DYNAMIC_VAR, it calls HandleDynamicVar() which executes the shell command and stores the resolved value in the result map. At this point, result["DYNAMIC_VAR"] = "hello"

  2. Line 118 (the bug): ReplaceVars re-processes the original, unmodified c.TaskfileVars. In ReplaceVarWithExtra (templater.go):

  3. Any subsequent reference to DYNAMIC_VAR sees Value: nil → resolves to empty string.

Suggested Fix

The ReplaceVars call should only process variables that actually have Ref values set, leaving already-resolved sh: variables untouched:

for k, v := range c.TaskfileVars.All() {
    if v.Ref != "" {
        resolved := templater.ResolveRef(v.Ref, &templater.Cache{Vars: result})
        c.TaskfileVars.Set(k, ast.Var{Value: resolved})
    }
}

Minimal Reproducer

Taskfile.yml:

version: "3"

includes:
  other:
    taskfile: ./Other.yml
    internal: true

vars:
  DYNAMIC_VAR:
    sh: echo "hello"
  DERIVED_VAR: "{{.DYNAMIC_VAR}} world"

tasks:
  default:
    cmds:
      - 'echo "DYNAMIC_VAR={{.DYNAMIC_VAR}}"'
      - 'echo "DERIVED_VAR={{.DERIVED_VAR}}"'
    silent: true

Other.yml:

version: "3"

tasks:
  noop:
    cmds:
      - "true"

v3.48.0: DYNAMIC_VAR=hello, DERIVED_VAR=hello world
v3.49.0: DYNAMIC_VAR=, DERIVED_VAR= world

Environment

  • Task version: v3.49.0 (works on v3.48.0)
  • OS: Ubuntu 24.04 (linux/arm64, GitHub Actions runner)
  • Installed via: go-task/[email protected] (no version pin, so it picked up v3.49.0 automatically)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions