derailed/k9s · error

no describer for

Error message

no describer for %q

What it means

Describe.describe resolves the DAO accessor for a GVR and requires it to implement the dao.Describer interface (Describe/ToYAML). When the registered DAO does not, describe requests cannot be served and this error names the GVR.

Solutions

  1. Check which accessor is registered for the GVR in the DAO factory (metals/accessors registry)
  2. Make the custom DAO implement dao.Describer: add Describe(path string) (string, error) (and ToYAML) — usually by embedding dao.Resource
  3. For plain CRDs, rely on the generic accessor which provides describers via kubectl describe semantics
  4. As a workaround, describe via kubectl describe <resource> <name>

Example fix

// before: custom DAO without describer
type MyCRD struct {
  dao.NonResource
}

// after: embed Resource to gain Describer
type MyCRD struct {
  dao.Resource
}
Defensive patterns

Strategy: type-guard

Type guard

func describerFor(factory dao.Factory, gvr *client.GVR) (dao.Describer, bool) {
    accessor, err := dao.AccessorFor(factory, gvr)
    if err != nil { return nil, false }
    d, ok := accessor.(dao.Describer)
    return d, ok
}

Try / catch

desc, err := d.describe(ctx, gvr, path)
if err != nil && strings.Contains(err.Error(), "no describer for") {
    return "", fmt.Errorf("%w — resource type has no describe support; use 'kubectl describe' instead", err)
}

Prevention

When it happens

Trigger: Describing a resource whose DAO accessor is a bare type without Describe/ToYAML methods — typically custom resources routed to a generic accessor that was constructed without describer support, or a plugin/custom DAO registration that forgot the methods.

Common situations: Adding custom resources to k9s views; a custom DAO that embeds dao.Resource but overrides enough to lose the interface; referencing resources an extension API server serves without standard describe semantics.

Related errors


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

Appendix: source

Thrown at internal/model/describe.go:182

	lines := strings.Split(s, "\n")
	if reflect.DeepEqual(lines, d.lines) {
		return nil
	}
	d.lines = lines
	d.fireResourceChanged(d.lines, d.filter(d.query, d.lines))

	return nil
}

// Describe describes a given resource.
func (d *Describe) describe(ctx context.Context, gvr *client.GVR, path string) (string, error) {
	meta, err := getMeta(ctx, gvr)
	if err != nil {
		return "", err
	}
	desc, ok := meta.DAO.(dao.Describer)
	if !ok {
		return "", fmt.Errorf("no describer for %q", meta.DAO.GVR())
	}
	if desc, ok := meta.DAO.(*dao.Secret); ok {
		desc.SetDecodeData(d.decode)
	}

	return desc.Describe(path)
}

// AddListener adds a new model listener.
func (d *Describe) AddListener(l ResourceViewerListener) {
	d.listeners = append(d.listeners, l)
}

// RemoveListener delete a listener from the list.
func (d *Describe) RemoveListener(l ResourceViewerListener) {
	victim := -1
	for i, lis := range d.listeners {
		if lis == l {

View on GitHub (pinned to 2d3ccc6ba2)