GoogleContainerTools/skaffold · error
unable to evaluate build args: %w
Error message
unable to evaluate build args: %w
What it means
expandBuildArgs first evaluates all user-supplied build args as env-style templates; any failure (unset referenced variable, malformed ${...} expression) is wrapped as 'unable to evaluate build args'. Called directly from ReadCopyCmdsFromDockerfile, so dependency extraction stops before ARG substitution into the AST.
Source
Thrown at pkg/skaffold/docker/parse.go:174
return nil, fmt.Errorf("parsing dockerfile: %w", err)
}
m := make(map[string]*string)
for _, n := range res.AST.Children {
if strings.ToLower(n.Value) != command.Arg {
continue
}
k := strings.SplitN(n.Next.Value, "=", 2)[0]
if v, ok := buildArgs[k]; ok {
m[k] = v
}
}
return m, nil
}
func expandBuildArgs(nodes []*parser.Node, buildArgs map[string]*string) error {
args, err := util.EvaluateEnvTemplateMap(buildArgs)
if err != nil {
return fmt.Errorf("unable to evaluate build args: %w", err)
}
for i, node := range nodes {
if strings.ToLower(node.Value) != command.Arg {
continue
}
// build arg's key
keyValue := strings.Split(node.Next.Value, "=")
key := keyValue[0]
// build arg's value
var value string
if args[key] != nil {
value = *args[key]
} else if len(keyValue) > 1 {
value = keyValue[1]
}View on GitHub (pinned to a1189de023)
Solutions
- Export the referenced variable in the environment where Skaffold runs
- Add a fallback default in the arg value ('${VAR:-fallback}') or in the Dockerfile ARG declaration
- Fix unbalanced braces / invalid expansion syntax in the build-arg value
- Log or print util.EvaluateEnvTemplateMap's inner error to identify exactly which key failed and correct it
Example fix
// before
buildArgs:
VERSION: $APP_VERSION
// after
buildArgs:
VERSION: ${APP_VERSION:-0.0.0} Defensive patterns
Strategy: validation
Validate before calling
func preflightBuildArgs(buildArgs map[string]*string, env func(string) string) error {
for k, v := range buildArgs {
if v == nil { continue }
for _, m := range varRefRe.FindAllStringSubmatch(*v, -1) {
name := m[1]
if !strings.Contains(*v, ":-"+name) && env(name) == "" {
return fmt.Errorf("build arg %q references unset env var %q", k, name)
}
}
}
return nil
}
var varRefRe = regexp.MustCompile(`\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?`) Type guard
func allArgsEvaluate(buildArgs map[string]*string) bool {
_, err := util.EvaluateEnvTemplateMap(buildArgs)
return err == nil
} Try / catch
err := skaffoldExpandArgs(nodes, buildArgs)
if err != nil && strings.Contains(err.Error(), "unable to evaluate build args") {
for k, v := range buildArgs {
if v == nil || !hasBalancedTemplate(*v) || referencesUnsetEnv(*v) {
log.Printf("problematic build arg %s=%v", k, v)
}
}
return err
} Prevention
- Mirror CI env vars locally when reproducing — the failure is usually environment-dependent
- Always give Dockerfile ARGs defaults so missing env vars degrade gracefully
- Evaluate build args yourself (util.EvaluateEnvTemplateMap) as a preflight to identify the failing key
- Watch for shell/yaml layers stripping '$' or braces from arg values
When it happens
Trigger: ReadCopyCmdsFromDockerfile called with a buildArgs map where a value like '$UNSET_VAR' or '${A:-${B}}' cannot be resolved by util.EvaluateEnvTemplateMap against the process environment.
Common situations: Local shell has the variable but the Skaffold process (IDE plugin, container, CI job) does not; nested or escaped dollar signs mangled by yaml/shell quoting layers; typos in variable names.
Related errors
- putting build arguments: %w
- unable to lookup minikube executable. Please add it to PATH
- executing template: %w
- unsupported template: %s
- setting template flag: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/55f2cd02e7923595.
Report an issue: GitHub.