derailed/k9s · error

expecting context Path

Error message

expecting context Path

What it means

Reference.Scan has already run ScanForRefs successfully, then reads the resource FQN from ctx.Value(internal.KeyPath) to namespace the rendered ReferenceRes rows. If no string was stored under internal.KeyPath the scan results are discarded and this error returned. The key carries the selected resource path (namespace/name) set by the invoking view.

Source

Thrown at internal/dao/reference.go:51

		return r.Scan(ctx)
	}
}

// Get fetch a given reference.
func (*Reference) Get(context.Context, string) (runtime.Object, error) {
	panic("NYI")
}

// Scan scan cluster resources for references.
func (r *Reference) Scan(ctx context.Context) ([]runtime.Object, error) {
	refs, err := ScanForRefs(ctx, r.Factory)
	if err != nil {
		return nil, err
	}

	fqn, ok := ctx.Value(internal.KeyPath).(string)
	if !ok {
		return nil, errors.New("expecting context Path")
	}
	ns, _ := client.Namespaced(fqn)
	oo := make([]runtime.Object, 0, len(refs))
	for _, ref := range refs {
		_, n := client.Namespaced(ref.FQN)
		oo = append(oo, render.ReferenceRes{
			Namespace: ns,
			Name:      n,
			GVR:       ref.GVR,
		})
	}

	return oo, nil
}

// ScanSA scans for serviceaccount refs.
func (r *Reference) ScanSA(ctx context.Context) ([]runtime.Object, error) {
	refs, err := ScanForSARefs(ctx, r.Factory)

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Set the path before scanning: ctx = context.WithValue(ctx, internal.KeyPath, fqn) where fqn is the selected resource's namespace/name.
  2. Reuse the context-building helpers in internal/view (e.g. browser.go:637-638 sets KeyGVR and KeyPath together) so both keys are always present.
  3. In tests, seed the context the way dao/container_test.go:34 does: context.WithValue(context.Background(), internal.KeyPath, "ns/name").

Example fix

// before
ctx := context.Background()
oo, err := ref.List(ctx, "") // -> expecting context Path
// after
ctx = context.WithValue(ctx, internal.KeyGVR, client.SecGVR)
ctx = context.WithValue(ctx, internal.KeyPath, "default/my-secret")
oo, err := ref.List(ctx, "")
Defensive patterns

Strategy: validation

Validate before calling

func withPath(ctx context.Context, fqn string) context.Context {
    return context.WithValue(ctx, internal.KeyPath, fqn)
}

if _, ok := ctx.Value(internal.KeyPath).(string); !ok {
    ctx = withPath(ctx, "default/my-secret")
}

Type guard

func pathFromCtx(ctx context.Context) (string, bool) {
    p, ok := ctx.Value(internal.KeyPath).(string)
    return p, ok
}

Prevention

When it happens

Trigger: Invoking Reference.List/Scan with a context missing context.WithValue(ctx, internal.KeyPath, fqn); KeyPath present but holding a non-string value so the type assertion fails.

Common situations: Custom views or tests calling the references DAO directly; a navigation path that builds a fresh context for the reference view but forgets to propagate the selected item's path (compare view/helpers.go:136 and view/browser.go:638 which set it).

Related errors


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