derailed/k9s · warning

%s

Error message

%s

What it means

HelmChart.Uninstall (internal/dao/helm_chart.go:124-144) runs the helm uninstall action. If u.Run succeeds (err == nil) but the response carries a non-empty Info string, k9s returns it AS an error via fmt.Errorf("%s", res.Info). Helm fills Info with post-uninstall messages such as kept-hook warnings or notes about resources pending deletion, so a technically successful uninstall can surface here as an error.

Source

Thrown at internal/dao/helm_chart.go:140

}

// Uninstall uninstalls a HelmChart.
func (h *HelmChart) Uninstall(path string, keepHist bool) error {
	ns, n := client.Namespaced(path)
	flags := h.Client().Config().Flags()
	cfg, err := ensureHelmConfig(flags, ns)
	if err != nil {
		return err
	}

	u := action.NewUninstall(cfg)
	u.KeepHistory = keepHist
	res, err := u.Run(n)
	if err != nil {
		return err
	}
	if res != nil && res.Info != "" {
		return fmt.Errorf("%s", res.Info)
	}

	return nil
}

// ensureHelmConfig return a new configuration.
func ensureHelmConfig(flags *genericclioptions.ConfigFlags, ns string) (*action.Configuration, error) {
	settings := &genericclioptions.ConfigFlags{
		Namespace:        &ns,
		Context:          flags.Context,
		BearerToken:      flags.BearerToken,
		APIServer:        flags.APIServer,
		CAFile:           flags.CAFile,
		KubeConfig:       flags.KubeConfig,
		Impersonate:      flags.Impersonate,
		Insecure:         flags.Insecure,
		TLSServerName:    flags.TLSServerName,
		ImpersonateGroup: flags.ImpersonateGroup,

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Check the actual state: helm ls --all -n <ns> (or k9s Helm view) - the release is usually already gone
  2. Treat the message text as a warning: kept hooks/history mean cleanup may need --no-hooks or helm delete --keep-history awareness
  3. If history was kept unintentionally, re-run uninstall without keep-history or purge history
  4. Verify no orphaned resources remain: kubectl get all -n <ns> against the chart's manifest
Defensive patterns

Strategy: try-catch

Validate before calling

// Before uninstalling, confirm the release exists in the namespace.
func ReleaseExists(cfg *action.Configuration, ns, name string) bool {
	_, err := cfg.Releases.Last(name)
	return err == nil
}

Try / catch

err := h.Uninstall(path, keepHist)
if err != nil {
    // res.Info messages follow a successful uninstall: verify state, then downgrade to warning.
    if _, lsErr := action.NewList(cfg).Run(); lsErr == nil /* release gone */ {
        slog.Warn("helm uninstall info", slogs.Error, err)
        return nil // treat as success-with-warning
    }
    return err
}

Prevention

When it happens

Trigger: Deleting a Helm release from the Helm view where uninstall completes but helm attaches an Info message - e.g. release history kept (u.KeepHistory), hooks not deleted, or resources still terminating. Contrast: a genuinely missing release fails earlier at u.Run with helm's own error, not this one.

Common situations: Uninstalling with keep-history enabled; charts with pre/post-delete hooks that helm reports on; CI-shared clusters where another actor already removed the release's resources leaving stray Info.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/774cf9dbc738e791. Report an issue: GitHub.