GoogleContainerTools/skaffold · error · UserErr

Failed to render release

Error message

Failed to render release

What it means

Helm rendering wraps any failure of the `helm template`-style render invocation in a UserErr with the message "Failed to render release", attaching the combined helm stdout/stderr, error text, release name, and args as the inner error. This surfaces helm-level problems (bad chart, bad values, missing chart) during `skaffold render`/deploy.

Source

Thrown at pkg/skaffold/render/renderer/helm/helm.go:228

	// Build Chart dependencies, but allow a user to skip it.
	if !release.SkipBuildDependencies && release.ChartPath != "" {
		log.Entry(ctx).Info("Building helm dependencies...")
		args := h.depBuildArgs(release.ChartPath)
		if err := helm.ExecWithStdoutAndStderr(ctx, h, io.Discard, errBuffer, false, env, args...); err != nil {
			log.Entry(ctx).Info(errBuffer.String())
			return nil, helm.UserErr("building helm dependencies", err)
		}
	}

	err = helm.ExecWithStdoutAndStderr(ctx, h, outBuffer, errBuffer, release.UseHelmSecrets, env, args...)
	errorMsg := errBuffer.String()

	if len(errorMsg) > 0 {
		log.Entry(ctx).Info(errorMsg)
	}

	if err != nil {
		return nil, helm.UserErr("Failed to render release", errors.New(strings.TrimSpace(fmt.Sprintf("%s %s (releaseName=%q, args=%v)", outBuffer.String(), errorMsg, releaseName, args))))
	}

	return outBuffer.Bytes(), nil
}

func generateSkaffoldOverrides(release latest.HelmRelease) (func(), error) {
	if len(release.Overrides.Values) > 0 {
		overrides, err := yaml.Marshal(release.Overrides)
		if err != nil {
			return nil, helm.UserErr("cannot marshal overrides to create overrides values.yaml", err)
		}

		if err := os.WriteFile(constants.HelmOverridesFilename, overrides, 0o666); err != nil {
			return nil, helm.UserErr(fmt.Sprintf("cannot create file %q", constants.HelmOverridesFilename), err)
		}

		return func() {
			os.RemoveAll(constants.HelmOverridesFilename)

View on GitHub (pinned to a1189de023)

Solutions

  1. Read the wrapped inner error/log output (releaseName and args are included) and run the same helm command manually to reproduce
  2. Run `helm dependencies update` for the chart and verify chartPath and valuesFiles in skaffold.yaml
  3. Fix template/values errors indicated in helm output (e.g. `helm template <release> <chart> --debug`)

Example fix

// before
releases:
  - name: myapp
    chartPath: ./charts/myapp  # path does not exist
// after
releases:
  - name: myapp
    chartPath: ./chart       # corrected to actual chart directory
Defensive patterns

Strategy: fallback

Validate before calling

if _, err := os.Stat(release.ChartPath); err != nil { return fmt.Errorf("chartPath %q missing: %w", release.ChartPath, err) }
if err := helmDepUp(release.ChartPath); err != nil { return err }

Type guard

func chartExists(chartPath string) bool { fi, err := os.Stat(chartPath); return err == nil && fi.IsDir() }

Try / catch

manifest, err := generateHelmManifest(ctx, release, args)
if err != nil {
  log.Entry(ctx).Errorf("helm render failed for release %q: %v", release.Name, err) // inner error carries helm stdout/stderr
  return nil, err
}

Prevention

When it happens

Trigger: generateHelmManifest executes helm with the release args and helm exits nonzero (or reports errorMsg) — e.g. missing chart path, invalid values.yaml, template syntax errors, failed lookups.

Common situations: Chart path wrong or chart not fetched (missing dependencies); invalid values passed via `deploy.helm.releases` overrides; Helm version mismatch with chart template syntax.

Related errors


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