derailed/k9s · error

expecting a sanitizer for %q

Error message

expecting a sanitizer for %q

What it means

sanitizeCmd (internal/view/pod.go:266) asserts that the DAO for the viewer's GVR implements dao.Sanitizer (interface with Sanitize(ctx, ns)). Only the pod DAO implements it; any other accessor, or a customized pod DAO that drops the method, fails the assertion before the confirmation dialog is shown.

Source

Thrown at internal/view/pod.go:266

		return nil
	}

	if err := containerAttachIn(p.App(), p, path, ""); err != nil {
		p.App().Flash().Err(err)
	}

	return nil
}

func (p *Pod) sanitizeCmd(*tcell.EventKey) *tcell.EventKey {
	res, err := dao.AccessorFor(p.App().factory, p.GVR())
	if err != nil {
		p.App().Flash().Err(err)
		return nil
	}
	s, ok := res.(dao.Sanitizer)
	if !ok {
		p.App().Flash().Err(fmt.Errorf("expecting a sanitizer for %q", p.GVR()))
		return nil
	}

	msg := fmt.Sprintf("Sanitize deletes all pods in completed/error state\nPlease enter [orange::b]%s[-::-] to proceed.", magicPrompt)
	dialog.ShowConfirmAck(p.App().App, p.App().Content.Pages, magicPrompt, true, "Sanitize", msg, func() {
		ctx, cancel := context.WithTimeout(context.Background(), 5*p.App().Conn().Config().CallTimeout())
		defer cancel()
		total, err := s.Sanitize(ctx, p.GetTable().GetModel().GetNamespace())
		if err != nil {
			p.App().Flash().Err(err)
			return
		}
		p.App().Flash().Infof("Sanitized %d %s", total, p.GVR())
		p.Refresh()
	}, func() {})

	return nil
}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Run Sanitize from the real pods view (':po') where the pod DAO backs it
  2. Clean up completed/failed pods manually: 'kubectl delete pods -n <ns> --field-selector=status.phase=Succeeded,Failed'
  3. If custom DAO: implement dao.Sanitizer — Sanitize(ctx context.Context, ns string) (int, error)
  4. Remove the sanitize binding from viewers whose resources are not pods

Example fix

// before: sanitize bound on non-pod viewer
// -> expecting a sanitizer for "mygvr"

// after: keep sanitize on the pod DAO only
func (d *PodDAO) Sanitize(ctx context.Context, ns string) (int, error) {
  // delete pods in Succeeded/Failed phase, return count
}
Defensive patterns

Strategy: type-guard

Validate before calling

// only offer sanitize when the accessor implements dao.Sanitizer
if _, ok := res.(dao.Sanitizer); !ok {
    p.App().Flash().Err(fmt.Errorf("%s does not support sanitize", p.GVR()))
    return nil
}

Type guard

func isSanitizer(res dao.Resource) bool {
    _, ok := res.(dao.Sanitizer)
    return ok
}

Prevention

When it happens

Trigger: Pressing the sanitize keybinding on a viewer whose GVR's accessor lacks Sanitize — e.g. the keybinding was rebound/copied to another resource's browser, or a fork replaced the pod DAO.

Common situations: Custom keybinding maps that spread 'Sanitize' beyond the pod view; k9s forks with modified DAO registries; interface drift after upgrading k9s where Sanitize's signature changed.

Related errors


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