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
- Ignore the 'scalable' wording — the fix is pod-spec support, not scale subresource access
- Apply the same fixes as 235: use supported workloads or register a ContainsPodSpec DAO for the CRD
- 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
- Same gate as 235: assert ContainsPodSpec before enabling the set-image action
- Do not chase replicas — despite the wording, scalability is irrelevant to this failure
- Fix the copy if you maintain a fork: the message should name ContainsPodSpec
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
- expected SubjectRes, but got %T
- expecting a ContainsPodSpec for %q but got %T
- expecting a switchable resource
- expecting a switchable resource
- resource is not restartable
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/b911620ce4fe4ff0.
Report an issue: GitHub.