GoogleContainerTools/skaffold · error
unable to expand build args: %w
Error message
unable to expand build args: %w
What it means
Wraps a failure from util.EvaluateEnvTemplateMapWithEnv when expanding ${...} templates in build args. A referenced environment variable is unset (or a template is malformed), so the final build-arg map cannot be produced.
Source
Thrown at pkg/skaffold/docker/build_args.go:86
absDockerfilePath, err := NormalizeDockerfilePath(workspace, dockerfilePath)
if err != nil {
return nil, fmt.Errorf("normalizing dockerfile path: %w", err)
}
f, err := os.Open(absDockerfilePath)
if err != nil {
return nil, fmt.Errorf("reading dockerfile: %w", err)
}
defer f.Close()
result, err = filterUnusedBuildArgs(f, result)
if err != nil {
return nil, fmt.Errorf("removing unused default args: %w", err)
}
for k, v := range args {
result[k] = v
}
result, err = util.EvaluateEnvTemplateMapWithEnv(result, env)
if err != nil {
return nil, fmt.Errorf("unable to expand build args: %w", err)
}
return result, nil
}
// ArtifactResolver provides an interface to resolve built artifact tags by image name.
type ArtifactResolver interface {
GetImageTag(imageName string) (string, bool)
}
// ResolveDependencyImages creates a map of artifact aliases to their built image from a required artifacts slice.
// If `missingIsFatal` is false then it is permissive of missing entries in the ArtifactResolver and returns nil for those entries.
func ResolveDependencyImages(deps []*latest.ArtifactDependency, r ArtifactResolver, missingIsFatal bool) map[string]*string {
if r == nil {
// `diagnose` is called without an artifact resolver. Return an empty map in this case.
return nil
}
m := make(map[string]*string)
for _, d := range deps {View on GitHub (pinned to a1189de023)
Solutions
- Export the missing environment variable before running skaffold
- Use a default in the template: ${VAR:-default}
- Hard-code the value in skaffold.yaml if it is static
- Fix malformed template syntax in the build-arg value
Example fix
// before
build:
buildArgs:
USER: "{{.USER}}" # unset in CI
// after
build:
buildArgs:
USER: "${USER:-ci}" Defensive patterns
Strategy: validation
Validate before calling
for k, v := range buildArgs {
for _, m := range templateRegexp.FindAllStringSubmatch(v, -1) {
name := m[1]
if os.Getenv(name) == "" && !strings.Contains(v, name+":-") {
return fmt.Errorf("build arg %s references unset env var %s", k, name)
}
}
} Try / catch
args, err := evalBuildArgs(workspace, df, args, env)
if err != nil && strings.Contains(err.Error(), "unable to expand build args") {
return fmt.Errorf("missing env var for build args: %w", err)
} Prevention
- Provide defaults ${VAR:-default} in templated build args
- Document required env vars and set them in CI pipelines
- Validate env presence before invoking skaffold
- Avoid ${{VAR}} double-brace typos
When it happens
Trigger: evalBuildArgs calls EvaluateEnvTemplateMapWithEnv(result, env) and a build arg value like ${USER} or ${VAR:-default} with an unset required variable fails evaluation, or the template syntax is invalid.
Common situations: skaffold.yaml build args referencing env vars absent in CI; shell-expanded vars available locally but not in the build environment; typos like ${{VAR}}.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- unable to get value for key %q: %w
- `apply` requires at least one manifest argument
- `exec` requires exactly one action to execute
- `config-dependencies add` requires exactly one file path arg
- `jobManifestPaths modify` requires exactly one manifest file
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/0ce63f4f2290843a.
Report an issue: GitHub.