derailed/k9s · error

no path specified in context

Error message

no path specified in context

What it means

Returned by Benchmark DAO List (internal/dao/benchmark.go:50) when the context carries no internal.KeyPath string value. KeyPath selects which benchmark files to match: it is normalized (slashes replaced by '_' in its first segment, then BenchRx) into pathMatch used to filter os.ReadDir results by filename prefix. Missing/incorrectly-typed KeyPath aborts listing even when KeyDir was supplied.

Source

Thrown at internal/dao/benchmark.go:50

// 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())})
		}
	}

	return oo, nil

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Always pair both keys: WithValue(ctx, internal.KeyDir, dir) and WithValue(ctx, internal.KeyPath, path)
  2. Check the value type is exactly string (the ok from ctx.Value(...).(string)) — an int or custom type will fail the assertion
  3. Route calls through the view layer that builds this context; keep DAO usage internal

Example fix

// before
ctx := context.WithValue(context.Background(), internal.KeyDir, dir)
oo, err := bench.List(ctx, "")

// after
ctx := context.WithValue(ctx, internal.KeyPath, "allocs/scan")
oo, err := bench.List(ctx, "")
Defensive patterns

Strategy: validation

Validate before calling

func benchCtx(dir, path string) context.Context {
    ctx := context.WithValue(context.Background(), internal.KeyDir, dir)
    return context.WithValue(ctx, internal.KeyPath, path)
}

Try / catch

oo, err := benchDao.List(ctx, "")
if err != nil && strings.Contains(err.Error(), "no path specified in context") {
    ctx = context.WithValue(ctx, internal.KeyPath, wantPath)
    oo, err = benchDao.List(ctx, "")
}

Prevention

When it happens

Trigger: Calling List with KeyDir set but no context.WithValue(ctx, internal.KeyPath, p); storing a non-string under the key; or passing an empty-path variant of the call that skips enrichment.

Common situations: Same as [12] — custom DAO callers, tests, refactors losing the WithValue chain; navigating to the benchmark view root where code assumed a default path instead of injecting one.

Related errors


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