derailed/k9s · error

no dir in context

Error message

no dir in context

What it means

Dir is the DAO behind the local directory browser (view/dir.go) and reads the local filesystem, not the cluster. Because its List signature has no path parameter, the directory to browse must be carried in the context under internal.KeyPath as a string (internal/dao/dir.go:40). If the key is absent — not merely empty — List returns 'no dir in context' before touching the disk.

Source

Thrown at internal/dao/dir.go:40

// Dir tracks standard and custom command aliases.
type Dir struct {
	NonResource
}

// NewDir returns a new set of aliases.
func NewDir(f Factory) *Dir {
	var a Dir
	a.Init(f, client.DirGVR)
	return &a
}

var yamlRX = regexp.MustCompile(`.*\.(yml|yaml|json)`)

// List returns a collection of aliases.
func (*Dir) List(ctx context.Context, _ string) ([]runtime.Object, error) {
	dir, ok := ctx.Value(internal.KeyPath).(string)
	if !ok {
		return nil, errors.New("no dir in context")
	}

	files, err := os.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	oo := make([]runtime.Object, 0, len(files))
	for _, f := range files {
		if strings.HasPrefix(f.Name(), ".") || !f.IsDir() && !yamlRX.MatchString(f.Name()) {
			continue
		}
		oo = append(oo, render.DirRes{
			Path:  filepath.Join(dir, f.Name()),
			Entry: f,
		})
	}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Seed the key before listing: ctx = context.WithValue(ctx, internal.KeyPath, "/path/to/dir").
  2. When writing views, reuse the contextFn pattern from internal/view/dir.go instead of hand-building contexts.
  3. Ensure the value is a plain string; any other type fails the ctx.Value assertion silently.
  4. In tests, mirror internal/dao/dir_test.go which sets KeyPath to a testdata directory.

Example fix

// before
ctx := context.Background()
items, err := dirDAO.List(ctx, "") // -> no dir in context
// after
ctx := context.WithValue(context.Background(), internal.KeyPath, "/tmp/mydir")
items, err := dirDAO.List(ctx, "")
Defensive patterns

Strategy: validation

Validate before calling

if _, ok := ctx.Value(internal.KeyPath).(string); !ok {
    ctx = context.WithValue(ctx, internal.KeyPath, dirPath)
}
items, err := dirDAO.List(ctx, "")

Type guard

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

Prevention

When it happens

Trigger: Calling dao.Dir.List(ctx, "") with a context that never had context.WithValue(ctx, internal.KeyPath, dir). The stock views always inject it via view/dir.go's context function, so this is hit mainly in unit tests (compare internal/dao/dir_test.go which seeds it), plugins, or embedding code that passes context.Background().

Common situations: Programmatic use of the DAO layer outside the TUI; refactors that build a fresh context for a browser view and forget the path key; storing a non-string value under KeyPath so the type assertion fails (also reported as 'no dir in context').

Related errors


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