You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Nested include vars overridden by ancestor include vars
Description
This issue may be related to the Variables Megathread discussion (#2034) and the scoping proposal in #2035, but I want to report a specific behavior that appears to contradict the fix in PR #1256 ("fix: propagate include vars in multi-level includes").
I believe the behavior described here is an edge case not covered by #1256 or a regression of that PR, but apologies if this is the expected behavior or a duplicate issue.
Summary
In nested includes (A → B → C), vars explicitly passed in the child include (B → C) are overridden by vars from the ancestor include (A → B). The immediate parent's explicit vars declaration is ignored. This seems inconsistent with PR #1256's intent to properly propagate include vars in multi-level includes.
Minimal Reproduction
minimal_test/
├── Taskfile.yml # includes TasksLevel1 with EGVAR='INHERITED-root-value'
├── TasksLevel1.yml # includes TasksLevel2 with EGVAR='PASSED-via-includes-in-level1'
└── TasksLevel2.yml # expects 'PASSED-via-includes-in-level1', gets 'INHERITED-root-value'
# Nested includes: ancestor var overrides immediate parent's explicit var
$ task level1:level2:show
EGVAR=INHERITED-root-value
DERIVED_EGVAR=INHERITED-root-value-derived
# Direct invocation: immediate include var works correctly
$ task -t TasksLevel1.yml level2:show
EGVAR=PASSED-via-includes-in-level1
DERIVED_EGVAR=PASSED-via-includes-in-level1-derived
Expected Behavior
TasksLevel2.yml should receive EGVAR='PASSED-via-includes-in-level1' because that is what TasksLevel1.yml explicitly passes in its includes.
Task-Call-Time Vars Do Not Resolve This
Passing vars at task-call time (rather than include time) does not fully resolve this issue:
$ task level1:call-level2-workaround
EGVAR=PASSED-via-task-in-level1 # Task-call var works
DERIVED_EGVAR=INHERITED-root-value-derived # Global var still wrong
Task-call vars override EGVAR for task execution, but cannot affect DERIVED_EGVAR, which was already evaluated at include time using the (incorrect) ancestor value.
Why This Seems Like a Bug
Explicit declarations ignored: vars: { EGVAR: '...' } in an include statement is an explicit override. Silent replacement by an ancestor's value violates least-surprise.
Entry-point-dependent behavior: The same taskfile behaves differently depending on whether it is the root or included from a parent.
Nested include vars overridden by ancestor include vars
Description
This issue may be related to the Variables Megathread discussion (#2034) and the scoping proposal in #2035, but I want to report a specific behavior that appears to contradict the fix in PR #1256 ("fix: propagate include vars in multi-level includes").
I believe the behavior described here is an edge case not covered by #1256 or a regression of that PR, but apologies if this is the expected behavior or a duplicate issue.
Summary
In nested includes (A → B → C), vars explicitly passed in the child include (B → C) are overridden by vars from the ancestor include (A → B). The immediate parent's explicit
varsdeclaration is ignored. This seems inconsistent with PR #1256's intent to properly propagate include vars in multi-level includes.Minimal Reproduction
Taskfile.yml
TasksLevel1.yml
TasksLevel2.yml
Observed Behavior
Expected Behavior
TasksLevel2.ymlshould receiveEGVAR='PASSED-via-includes-in-level1'because that is whatTasksLevel1.ymlexplicitly passes in itsincludes.Task-Call-Time Vars Do Not Resolve This
Passing vars at task-call time (rather than include time) does not fully resolve this issue:
Task-call vars override
EGVARfor task execution, but cannot affectDERIVED_EGVAR, which was already evaluated at include time using the (incorrect) ancestor value.Why This Seems Like a Bug
Explicit declarations ignored:
vars: { EGVAR: '...' }in an include statement is an explicit override. Silent replacement by an ancestor's value violates least-surprise.Entry-point-dependent behavior: The same taskfile behaves differently depending on whether it is the root or included from a parent.
Contradicts fix: propagate include vars in multi-level includes #1256: PR fix: propagate include vars in multi-level includes #1256 fixed multi-level include var propagation. Vars now propagate, but with incorrect precedence—ancestor wins over immediate parent.
Related Issues
Version
3.46.3
Operating system
macOS 14.8.3
Experiments Enabled
No response
Example Taskfile
See above