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 = timeout

View on GitHub (pinned to 385e5ad92a)

Solutions

  1. Read the wrapped %w cause — fix the underlying variable error it reports (often a failing sh: command)
  2. Test the dynamic variable's command manually in the task directory
  3. Simplify variable definitions to isolate which variable fails compilation
  4. 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

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.