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

  1. Export the referenced variable in the environment where Skaffold runs
  2. Add a fallback default in the arg value ('${VAR:-fallback}') or in the Dockerfile ARG declaration
  3. Fix unbalanced braces / invalid expansion syntax in the build-arg value
  4. 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

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


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/55f2cd02e7923595. Report an issue: GitHub.