derailed/k9s · error
unexpected object type: %T
Error message
unexpected object type: %T
What it means
fetchResourceObject() calls accessor.Get(ctx, path) and asserts the result to *unstructured.Unstructured. Some registered DAOs return typed runtime objects (e.g. *corev1.Pod) instead of unstructured; when a custom jump's source GVR is backed by such a typed DAO, the assertion fails and returns this error. Note fetchResourceObject runs unconditionally at the top of customJump, so any typed-DAO source breaks all custom jumps from that resource.
Source
Thrown at internal/view/custom_jump.go:120
return nil
}
// fetchResourceObject retrieves the full resource object for templating.
func fetchResourceObject(app *App, gvr *client.GVR, path string) (map[string]any, error) {
accessor, err := dao.AccessorFor(app.factory, gvr)
if err != nil {
return nil, err
}
o, err := accessor.Get(context.Background(), path)
if err != nil {
return nil, err
}
u, ok := o.(*unstructured.Unstructured)
if !ok {
return nil, fmt.Errorf("unexpected object type: %T", o)
}
return u.Object, nil
}
// determineTargetNamespace determines which namespace to use for the target resource.
func determineTargetNamespace(sourcePath, targetNSConfig string, sourceObj map[string]any) (string, error) {
sourceNS, _ := client.Namespaced(sourcePath)
switch targetNSConfig {
case "":
// Default: use the source resource's namespace
// If source is cluster-scoped, use ClusterScope
if client.IsClusterScoped(sourceNS) {
return client.ClusterScope, nil
}
return sourceNS, nil
case "all":View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Point the jump rule at a source GVR whose DAO returns unstructured data (most CRDs and generic resources)
- Test with a different source kind to confirm the typed-DAO hypothesis (the %T in the message names the concrete type)
- Upgrade k9s — newer builds handle typed objects via conversion or report this as a known limitation; file an issue with the %T value if it persists
Defensive patterns
Strategy: type-guard
Type guard
func toUnstructured(o runtime.Object) (*unstructured.Unstructured, error) {
if u, ok := o.(*unstructured.Unstructured); ok {
return u, nil
}
u := &unstructured.Unstructured{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(
mustToMap(o), u.Object); err != nil {
return nil, fmt.Errorf("cannot convert %T to unstructured: %w", o, err)
}
return u, nil
} Prevention
- When extending fetchResourceObject, use the ok-form assertion and convert typed objects instead of failing
- Author jump rules against CRDs/generic resources that always resolve to unstructured
- Log the %T value — it identifies exactly which DAO needs a conversion path
When it happens
Trigger: Defining a jump rule whose source is a resource whose DAO returns a typed object rather than unstructured — commonly core/typed resources like pods, nodes, or secrets depending on k9s version.
Common situations: Jump rules authored for pod->X or secret->Y navigation; k9s upgrades that converted a DAO from generic (unstructured) to typed; CRDs are safe (always unstructured), built-ins vary.
Related errors
- failed to fetch source resource: %w
- expecting a switchable resource
- expecting a switchable resource
- resource is not restartable
- expecting a ForwardRes but got %T
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/c38960930d043f3b.
Report an issue: GitHub.