derailed/k9s · error

no benchmark dir found in context

Error message

no benchmark dir found in context

What it means

Returned by Benchmark DAO List (internal/dao/benchmark.go:46) when the context.Context passed to List lacks the internal.KeyDir value (a string). The benchmark feature reads profiling/census benchmark files from a directory supplied via context; KeyDir points at the directory containing the benchmark output files. Missing key means List was invoked outside the benchmark view plumbing that injects it.

Source

Thrown at internal/dao/benchmark.go:46

type Benchmark struct {
	NonResource
}

// Delete nukes a resource.
func (*Benchmark) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, _ Grace) error {
	return os.Remove(path)
}

// Get returns a resource.
func (*Benchmark) Get(context.Context, string) (runtime.Object, error) {
	panic("NYI")
}

// List returns a collection of resources.
func (*Benchmark) List(ctx context.Context, _ string) ([]runtime.Object, error) {
	dir, ok := ctx.Value(internal.KeyDir).(string)
	if !ok {
		return nil, errors.New("no benchmark dir found in context")
	}
	path, ok := ctx.Value(internal.KeyPath).(string)
	if !ok {
		return nil, errors.New("no path specified in context")
	}
	pathMatch := BenchRx.ReplaceAllString(strings.Replace(path, "/", "_", 1), "_")

	ff, err := os.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	oo := make([]runtime.Object, 0, len(ff))
	for _, f := range ff {
		if !strings.HasPrefix(f.Name(), pathMatch) {
			continue
		}
		if fi, err := f.Info(); err == nil {
			oo = append(oo, render.BenchInfo{File: fi, Path: filepath.Join(dir, f.Name())})

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Inject the benchmark directory before listing: ctx = context.WithValue(ctx, internal.KeyDir, dir) using the same internal key package the views use
  2. Prefer calling through the benchmark view/factory so the context is assembled correctly
  3. In tests, build the context exactly as view/benchmark.go does (KeyDir + KeyPath)
  4. Copy the pattern from existing callers: search for KeyDir usages and mirror them

Example fix

// before
bench := dao.Benchmark{}
oo, err := bench.List(context.Background(), "")

// after
ctx := context.WithValue(context.Background(), internal.KeyDir, "/tmp/bench")
ctx = context.WithValue(ctx, internal.KeyPath, "cpu/profile")
oo, err := bench.List(ctx, "")
Defensive patterns

Strategy: validation

Validate before calling

func withBenchDir(ctx context.Context, dir string) context.Context {
    return context.WithValue(ctx, internal.KeyDir, dir)
}
// call sites always use the helper

Try / catch

oo, err := benchDao.List(ctx, "")
if err != nil && strings.Contains(err.Error(), "no benchmark dir found in context") {
    // re-build ctx with KeyDir and retry once
}

Prevention

When it happens

Trigger: Calling dao Benchmark.List(ctx, ...) with a plain context.Background()/TODO, or any path that forgets context.WithValue(ctx, internal.KeyDir, dir); also if the value stored is not a string (type assertion !ok).

Common situations: Reusing the DAO layer from custom code or tests without replicating the view's context enrichment; refactors that dropped the WithValue calls; invoking List programmatically for tooling.

Related errors


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