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

  1. Point the jump rule at a source GVR whose DAO returns unstructured data (most CRDs and generic resources)
  2. Test with a different source kind to confirm the typed-DAO hypothesis (the %T in the message names the concrete type)
  3. 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 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


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