derailed/k9s · error
expecting a job resource
Error message
expecting a job resource
What it means
Job.TailLogs fetches one Job from the informer cache and converts it into batchv1.Job to read its selector before delegating to podLogs (internal/dao/job.go:85). If conversion fails, the sentinel 'expecting a job resource' (lowercase 'a') is returned and the real converter error is discarded, so the offending field is invisible. It fires before any log streaming starts.
Source
Thrown at internal/dao/job.go:85
ll = append(ll, o)
}
}
}
return ll, nil
}
// TailLogs tail logs for all pods represented by this Job.
func (j *Job) TailLogs(ctx context.Context, opts *LogOptions) ([]LogChan, error) {
o, err := j.getFactory().Get(j.gvr, opts.Path, true, labels.Everything())
if err != nil {
return nil, err
}
var job batchv1.Job
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &job)
if err != nil {
return nil, errors.New("expecting a job resource")
}
if job.Spec.Selector == nil || len(job.Spec.Selector.MatchLabels) == 0 {
return nil, fmt.Errorf("no valid selector found for job: %s", opts.Path)
}
return podLogs(ctx, job.Spec.Selector.MatchLabels, opts)
}
func (j *Job) GetInstance(fqn string) (*batchv1.Job, error) {
o, err := j.getFactory().Get(j.gvr, fqn, true, labels.Everything())
if err != nil {
return nil, err
}
var job batchv1.Job
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &job)
if err != nil {View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Inspect the job: kubectl get job.batch <name> -n <ns> -o yaml and fix unexpected or mistyped fields.
- Upgrade k9s to a build whose k8s.io/* dependencies match the cluster minor version.
- Confirm jobs.batch is served by the core apiserver.
- Restart k9s to rebuild informer caches.
- If embedding, wrap the converter error with %w to reveal the offending field.
Example fix
// before
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &job)
if err != nil {
return nil, errors.New("expecting a job resource")
}
// after
u, ok := o.(*unstructured.Unstructured)
if !ok {
return nil, fmt.Errorf("expected unstructured job, got %T", o)
}
var job batchv1.Job
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &job); err != nil {
return nil, fmt.Errorf("job %q does not match v1 schema: %w", opts.Path, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
o, err := factory.Get(client.JobGVR, opts.Path, true, labels.Everything())
if err != nil { return err }
u, ok := o.(*unstructured.Unstructured)
if !ok || u.GroupVersionKind().Kind != "Job" {
return fmt.Errorf("not a job: %s", u.GroupVersionKind())
} Type guard
func isJob(o runtime.Object) bool {
u, ok := o.(*unstructured.Unstructured)
return ok && u.GroupVersionKind().Kind == "Job" && u.GroupVersionKind().Group == "batch"
} Try / catch
var job batchv1.Job
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &job); err != nil {
return nil, fmt.Errorf("job %q conversion: %w", opts.Path, err)
} Prevention
- Check log-tail failures against the object's raw YAML before blaming permissions.
- Keep k9s and cluster versions aligned; job schemas evolve across releases.
- Wrap converter errors with %w in any custom tailing code.
- Restart k9s after cluster upgrades to refresh informer caches.
When it happens
Trigger: Pressing the logs key on a Job whose stored object cannot convert to the compiled batchv1.Job struct — fields added or retyped by a newer/older apiserver, an aggregated API shadowing jobs.batch, or webhook-patched out-of-schema values. Also hit by embedding code calling TailLogs on such an object.
Common situations: Log tailing failing on specific jobs after cluster upgrades while k9s uses older k8s.io/api; jobs mutated by custom controllers with legacy fields; version skew between k9s and the cluster.
Related errors
- expecting Job resource
- expecting cronjob resource
- expecting Deployment resource
- expecting ServiceAccount resource
- expecting a context factory
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/942d2c4221599711.
Report an issue: GitHub.