derailed/k9s · error

expecting a scalable resource for %q

Error message

expecting a scalable resource for %q

What it means

ImageExtender.setImages() performs the same res.(dao.ContainsPodSpec) assertion before SetImages, but the message wrongly says 'expecting a scalable resource' — copy-paste from the scaler; the real requirement is ContainsPodSpec, not dao.Scalable. Functionally identical to error 235: the GVR's DAO cannot set images because it has no pod-spec support.

Source

Thrown at internal/view/image_extender.go:187

		return nil, err
	}
	resourceWPodSpec, ok := res.(dao.ContainsPodSpec)
	if !ok {
		return nil, fmt.Errorf("expecting a ContainsPodSpec for %q but got %T", s.GVR(), res)
	}

	return resourceWPodSpec.GetPodSpec(path)
}

func (s *ImageExtender) setImages(ctx context.Context, path string, imageSpecs dao.ImageSpecs) error {
	res, err := dao.AccessorFor(s.App().factory, s.GVR())
	if err != nil {
		return err
	}

	resourceWPodSpec, ok := res.(dao.ContainsPodSpec)
	if !ok {
		return fmt.Errorf("expecting a scalable resource for %q", s.GVR())
	}

	return resourceWPodSpec.SetImages(ctx, path, imageSpecs)
}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Ignore the 'scalable' wording — the fix is pod-spec support, not scale subresource access
  2. Apply the same fixes as 235: use supported workloads or register a ContainsPodSpec DAO for the CRD
  3. Upstream note: the message in image_extender.go should read 'expecting a ContainsPodSpec resource' — patch it if you build k9s from source

Example fix

// before (internal/view/image_extender.go) — misleading message
return fmt.Errorf("expecting a scalable resource for %q", s.GVR())
// after — matches the actual interface requirement
return fmt.Errorf("expecting a ContainsPodSpec resource for %q", s.GVR())
Defensive patterns

Strategy: type-guard

Type guard

func canSetImages(res dao.Resource) (dao.ContainsPodSpec, bool) {
    cps, ok := res.(dao.ContainsPodSpec)
    return cps, ok
}

if cps, ok := canSetImages(res); !ok {
    return fmt.Errorf("expecting a ContainsPodSpec resource for %q", s.GVR()) // fixed wording
} else {
    return cps.SetImages(ctx, path, imageSpecs)
}

Prevention

When it happens

Trigger: Confirming an image change on a resource whose DAO lacks ContainsPodSpec — generic CRD accessors, non-workload resources, or misregistered plugins.

Common situations: Same as 235, hit at commit time instead of read time: reading the pod spec happened to be skipped or succeeded via a different path, then SetImages fails; users mislead by 'scalable' into debugging replicas they never touched.

Related errors


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