derailed/k9s · error
expecting context Path
Error message
expecting context Path
What it means
Returned by ScanForRefs (internal/dao/cluster.go:65) when ctx.Value(internal.KeyPath) is not a string. KeyPath carries the FQN of the origin resource being scanned for (the value named fqn downstream, passed to each scanner's Scan(ctx, fqn, wait)). It is checked right after KeyGVR; missing it aborts before the goroutine fan-out.
Source
Thrown at internal/dao/cluster.go:65
func scanners() map[*client.GVR]RefScanner {
return map[*client.GVR]RefScanner{
client.DpGVR: new(Deployment),
client.DsGVR: new(DaemonSet),
client.StsGVR: new(StatefulSet),
client.CjGVR: new(CronJob),
client.JobGVR: new(Job),
}
}
// ScanForRefs scans cluster resources for resource references.
func ScanForRefs(ctx context.Context, f Factory) (Refs, error) {
rgvr, ok := ctx.Value(internal.KeyGVR).(*client.GVR)
if !ok {
return nil, errors.New("expecting context GVR")
}
fqn, ok := ctx.Value(internal.KeyPath).(string)
if !ok {
return nil, errors.New("expecting context Path")
}
wait, ok := ctx.Value(internal.KeyWait).(bool)
if !ok {
slog.Warn("Expecting context Wait key. Using default")
}
var wg sync.WaitGroup
out := make(chan Refs)
for gvr, scanner := range scanners() {
wg.Add(1)
go func(ctx context.Context, gvr *client.GVR, s RefScanner, out chan Refs, wait bool) {
defer wg.Done()
s.Init(f, gvr)
refs, err := s.Scan(ctx, rgvr, fqn, wait)
if err != nil {
slog.Error("Reference scan failed for",
slogs.RefType, fmt.Sprintf("%T", s),
slogs.Error, err,View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Always inject KeyPath alongside KeyGVR: context.WithValue(ctx, internal.KeyPath, fqn) with fqn a plain string
- Centralize context construction in one helper so the three keys (GVR, Path, Wait) are never partially set
- Add a unit test asserting ScanForRefs succeeds with the helper-built context
Example fix
// before ctx := context.WithValue(ctx, internal.KeyGVR, gvr) refs, err := dao.ScanForRefs(ctx, factory) // after ctx = context.WithValue(ctx, internal.KeyPath, client.FQN(ns, name)) refs, err := dao.ScanForRefs(ctx, factory)
Defensive patterns
Strategy: validation
Validate before calling
if _, ok := ctx.Value(internal.KeyPath).(string); !ok {
ctx = context.WithValue(ctx, internal.KeyPath, fqn)
}
refs, err := dao.ScanForRefs(ctx, factory) Type guard
func hasPathKey(ctx context.Context) bool {
_, ok := ctx.Value(internal.KeyPath).(string)
return ok
} Try / catch
refs, err := dao.ScanForRefs(ctx, factory)
if err != nil && strings.Contains(err.Error(), "expecting context Path") {
ctx = context.WithValue(ctx, internal.KeyPath, fqn)
refs, err = dao.ScanForRefs(ctx, factory)
} Prevention
- Treat KeyGVR/KeyPath/KeyWait as one bundle — set them together
- Keep the FQN a plain string (client.FQN output)
- Route ref scans through the view layer that owns context assembly
When it happens
Trigger: Calling ScanForRefs with KeyGVR set but omitting WithValue(ctx, internal.KeyPath, fqn); storing a non-string (e.g. a typed FQN struct) under the key.
Common situations: Same class as [14]: direct DAO invocation from tests/tools; context built by helper that only forwards some keys; refactor renamed the path key constant and call sites drifted.
Related errors
- expecting context GVR
- no benchmark dir found in context
- no path specified in context
- expecting context Wait
- no dir in context
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/efad13a3f512f712.
Report an issue: GitHub.