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
- Inject the benchmark directory before listing: ctx = context.WithValue(ctx, internal.KeyDir, dir) using the same internal key package the views use
- Prefer calling through the benchmark view/factory so the context is assembled correctly
- In tests, build the context exactly as view/benchmark.go does (KeyDir + KeyPath)
- 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
- Wrap DAO calls with a context-builder helper that sets both KeyDir and KeyPath
- Never pass context.Background() straight into DAO List
- Keep benchmark-directory wiring in one place (the view layer)
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
- no path specified in context
- expecting context GVR
- expecting context Path
- expecting context Wait
- no dir in context
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/7ee8d22391da29a5.
Report an issue: GitHub.