go-task/task · error · TaskfileInvalidError
loop var must be a delimiter-separated string, list or a map
Error message
loop var must be a delimiter-separated string, list or a map
What it means
Raised by itemsFromFor (called via compiledTask) when a `for` loop's `var` does not expand to one of the supported iterable shapes: a delimiter-separated string (e.g. comma-separated with `split:`), a list (Go/JSON-style array), or a map. When the resolved variable's underlying value is any other type, the executor returns this TaskfileInvalidError wrapping the message, tagged with the Taskfile location.
Source
Thrown at variables.go:458
values = asAnySlice(strings.Split(value, f.Split))
} else {
values = asAnySlice(strings.Fields(value))
}
case []string:
values = asAnySlice(value)
case []int:
values = asAnySlice(value)
case []any:
values = value
case map[string]any:
for k, v := range value {
keys = append(keys, k)
values = append(values, v)
}
default:
return nil, nil, errors.TaskfileInvalidError{
URI: location.Taskfile,
Err: errors.New("loop var must be a delimiter-separated string, list or a map"),
}
}
}
}
}
return values, keys, nil
}
// resolveMatrixRefs resolves any `ref:` rows in matrix and returns a new
// Matrix with those rows populated. It must not mutate the matrix passed in:
// that matrix is part of the shared, cached Task AST, and concurrent
// invocations of the same task (e.g. via parallel deps) call this with the
// same *ast.Matrix and would otherwise race on the row.Value assignment
// below, intermittently leaking a value resolved for one caller into another
// caller's expansion. See #2890.
func resolveMatrixRefs(matrix *ast.Matrix, cache *templater.Cache) (*ast.Matrix, error) {
if matrix.Len() == 0 {
return matrix, nilView on GitHub (pinned to 385e5ad92a)
Solutions
- Check what the variable actually resolves to (print it in a task cmd) and ensure it is a list or map
- If looping a plain string, add `split:` under the `for` block, e.g. `for: {var: ITEMS, split: ','}`
- Fix the variable definition so it is a YAML list/map, or the loop's var name typo
- Verify YAML quoting so list values are not collapsed into one scalar string
Example fix
# before
vars:
SERVICES: api web worker
tasks:
build:
cmds:
- for: { var: SERVICES }
task: build-one
# after
tasks:
build:
cmds:
- for: { var: SERVICES, split: ' ' }
task: build-one Defensive patterns
Strategy: validation
Validate before calling
# Ensure loop variables are lists/maps or configure split before running task:
vars:
SERVICES: [api, web, worker]
cmds:
- for: { var: SERVICES }
task: build-one Try / catch
if err := e.Run(ctx, task, call); err != nil {
var terr *errors.TaskfileInvalidError
if errors.As(err, &terr) && strings.Contains(err.Error(), "loop var must be") {
return fmt.Errorf("fix `for: var:` in %s: %w", terr.URI, err)
}
return err
} Prevention
- Define loop sources as YAML lists or maps; never loop a bare scalar string without `split:`
- Double-check the variable name in `for: var:` for typos against declared vars
- If the var comes from a command substitution, pair it with `split:` or structure its output as a list
- Run `task --list` or a dry run after Taskfile edits to catch loop-shape errors early
When it happens
Trigger: A task uses `for: {var: NAME, ...}` where NAME resolves to a scalar/bool/other non-iterable value — e.g. the variable was set to a plain string without `split:` configured, to a number, to a command substitution result used directly without split, or the var name is misspelled so it resolves to an unexpected value.
Common situations: Typo in the variable name inside `for: var:`; forgetting `split: ','` when looping over a plain string; looping over a variable produced by a command that returns a single value instead of a list; YAML that quotes a list into a single string.
Related errors
- task: Included Taskfiles can't have dotenv declarations. Ple
- task: precondition not met
- task: invalid run "%s"
- task: %w "%s"
- task: output style %q not recognized
AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05).
Data as JSON: /api/errors/0efa56c8c535eb9f.
Report an issue: GitHub.