go-task/task · error
task: failed to get variables: %w
Error message
task: failed to get variables: %w
What it means
While executing a command, runCommand first fetches the task's variables via FastGetVariables; if that fails, the command can't be templated and this error wraps the underlying cause. It indicates the variable-compilation stage (including dynamic sh:/cmd: variables) failed before the command even ran.
Source
Thrown at task.go:428
return nil
}
if e.Verbose || (!call.Silent && !cmd.Silent && !t.IsSilent() && !e.Taskfile.Silent && !e.Silent) {
e.Logger.Errf(logger.Green, "task: [%s] %s\n", t.Name(), cmd.LogCmd)
}
if e.Dry {
return nil
}
outputWrapper := e.Output
if t.Interactive {
outputWrapper = output.Interleaved{}
}
vars, err := e.Compiler.FastGetVariables(t, call)
outputTemplater := &templater.Cache{Vars: vars}
if err != nil {
return fmt.Errorf("task: failed to get variables: %w", err)
}
stdOut, stdErr, closer := outputWrapper.WrapWriter(e.Stdout, e.Stderr, t.Prefix, outputTemplater)
err = execext.RunCommand(ctx, &execext.RunCommandOptions{
Command: cmd.Cmd,
Dir: t.Dir,
Env: env.Get(t),
PosixOpts: slicesext.UniqueJoin(e.Taskfile.Set, t.Set, cmd.Set),
BashOpts: slicesext.UniqueJoin(e.Taskfile.Shopt, t.Shopt, cmd.Shopt),
Stdin: e.Stdin,
Stdout: stdOut,
Stderr: stdErr,
})
if closeErr := closer(err); closeErr != nil {
e.Logger.Errf(logger.Red, "task: unable to close writer: %v\n", closeErr)
}
if err != nil && timedOut(ctx, timeout) {
err = timeoutView on GitHub (pinned to 385e5ad92a)
Solutions
- Read the wrapped %w cause — fix the underlying variable error it reports (often a failing sh: command)
- Test the dynamic variable's command manually in the task directory
- Simplify variable definitions to isolate which variable fails compilation
- Ensure required tools/env for the variable commands exist in the execution environment
Example fix
# before
vars:
BRANCH:
sh: git rev-parse --abbrev-ref HEAD
# after
vars:
BRANCH:
sh: git rev-parse --abbrev-ref HEAD || echo unknown Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check dynamic variables before running the task
for _, v := range taskDef.Vars {
if v.Sh != "" {
if err := exec.Command("sh", "-c", v.Sh).Run(); err != nil {
return fmt.Errorf("dynamic var fails: %w", err)
}
}
} Try / catch
err := t.Run(ctx)
if err != nil && strings.Contains(err.Error(), "failed to get variables") {
// unwrap %w cause, fix the failing variable, then retry
var inner error
errors.As(err, &inner)
} Prevention
- Give every dynamic (sh:/cmd:) variable a non-zero-safe fallback
- Keep variable commands simple and dependency-free where possible
- Log the wrapped cause — the %w chain names the real failure
When it happens
Trigger: e.Compiler.FastGetVariables(t, call) returns an error during runCommand — typically because a dynamic (sh:/cmd:) variable inside the task or its dependencies failed to execute — right before wrapping writers for the command output.
Common situations: Dynamic variable commands failing (missing tools, non-zero exits), template compilation errors in variable resolution, or environment/directory problems making a variable's shell command fail. Usually the wrapped error points at the actual failing variable.
Related errors
AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05).
Data as JSON: /api/errors/c66efda896af1f03.
Report an issue: GitHub.