Skip to content

CLI variables lose nondeterministically against same-named globals from flattened includes #3069

Closed as duplicate

Description

@Paddione

CLI variables lose nondeterministically against same-named globals from flattened includes

Summary

When two or more flattened-included Taskfiles define the same global vars: name, a CLI-passed variable (task t ENV=x) does not reliably win. The winner is picked nondeterministically per process — the CLI value is just one candidate among the file values.

Observed on task 3.52.0 (linux) and setup-task v5 in CI.

Minimal reproduction

Taskfile.yml:

version: "3"
includes:
  w:
    taskfile: ./w.yml
    dir: .
    flatten: true
  m1:
    taskfile: ./m1.yml
    dir: .
    flatten: true
  m2:
    taskfile: ./m2.yml
    dir: .
    flatten: true
  m3:
    taskfile: ./m3.yml
    dir: .
    flatten: true
  m4:
    taskfile: ./m4.yml
    dir: .
    flatten: true

w.yml (defines the task, no globals):

version: "3"
tasks:
  t:
    vars:
      ENV: '{{.ENV | default "dev"}}'
    cmds:
      - echo "ENV={{.ENV}}"

m1.yml … m4.yml (each defines a global, e.g.):

version: "3"
vars:
  ENV: val-m1
tasks:
  dummy1:
    cmds:
      - echo m1

Run 12 times:

for i in $(seq 1 12); do task -n t ENV=cli-val; done

Result (actual): random pick across all five candidates, e.g.
val-m3, val-m1, cli-val, val-m2, val-m3, val-m1, val-m2, val-m2, val-m3, val-m2, val-m3, cli-val.

Expected: cli-val on every run — CLI variables should take precedence over file-defined variables.

Additional observations

  • With a single flattened include defining the global, the CLI variable is ignored deterministically (file value always wins), even for tasks without task-level vars:.
  • When the task's defining file declares the global itself, that file's value wins deterministically regardless of include order (not last-wins).
  • With no competing globals, behavior is correct: CLI wins, and the task-level {{.VAR | default ...}} fallback applies when no CLI value is given.
  • flatten only namespaces tasks; globals of all included files (flattened or not) land in the same pool.
  • Include-level vars: (e.g. dev-korczewski: vars: {ENV: korczewski}) deterministically beat CLI variables in our tests, before and after deduplicating file globals. Unsure whether that is intended; reporting for completeness.

Impact

Real-world case: a website:migrate task with an ENV whitelist precondition (dev|mentolder|korczewski|staging) randomly rendered ENV=mentolder despite ENV=bogus-... on the CLI, passing the precondition and targeting the wrong database — fail-open instead of fail-closed. Four unrelated flattened includes each defined a global ENV: mentolder.

Workaround

Remove all duplicate global definitions so each name exists at most once across the root Taskfile and all includes; move defaults to task-level vars: ('{{.ENV | default "..."}}'). Static task-level values are not a substitute — they shadow CLI variables unconditionally (also observed, presumably by design).

Activity

  1. vmaerten commented on Oct 12, 2026

    @vmaerten
    Member

    Hello
    Yes we already have an issue, see #1030
    This behavior will change in v4.
    Please avoid issue created only with AI.

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