derailed/k9s · error
expecting context Wait
Error message
expecting context Wait
What it means
Returned by ScanForSARefs (internal/dao/cluster.go:116) when ctx.Value(internal.KeyWait) is not a bool. KeyWait controls whether reference scans use the informer cache with wait (blocking sync) or hit the API directly. Notably ScanForRefs only logs a warning for the same omission, but ScanForSARefs treats it as a hard error.
Source
Thrown at internal/dao/cluster.go:116
}()
res := make(Refs, 0, 10)
for refs := range out {
res = append(res, refs...)
}
return res, nil
}
// ScanForSARefs scans cluster resources for serviceaccount refs.
func ScanForSARefs(ctx context.Context, f Factory) (Refs, error) {
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 {
return nil, errors.New("expecting context Wait")
}
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.ScanSA(ctx, fqn, wait)
if err != nil {
slog.Error("ServiceAccount scan failed",
slogs.RefType, fmt.Sprintf("%T", s),
slogs.Error, err,
)
return
}
select {View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Always set KeyWait explicitly: context.WithValue(ctx, internal.KeyWait, false) for instant (cache-less) scans or true to wait for cache sync
- Use one shared context-enrichment helper for both scans and include all keys even when optional elsewhere
- Keep the value a raw bool, not a pointer or custom type
Example fix
// before ctx := context.WithValue(ctx, internal.KeyPath, fqn) refs, err := dao.ScanForSARefs(ctx, factory) // after ctx = context.WithValue(ctx, internal.KeyWait, true) refs, err := dao.ScanForSARefs(ctx, factory)
Defensive patterns
Strategy: validation
Validate before calling
ctx = context.WithValue(ctx, internal.KeyWait, false) // or true to wait for cache sync refs, err := dao.ScanForSARefs(ctx, factory)
Try / catch
refs, err := dao.ScanForSARefs(ctx, factory)
if err != nil && strings.Contains(err.Error(), "expecting context Wait") {
ctx = context.WithValue(ctx, internal.KeyWait, true)
refs, err = dao.ScanForSARefs(ctx, factory)
} Prevention
- Always set KeyWait as a raw bool in scan contexts
- Do not share a partial context between the two scans without re-enrichment
- Encode the Wait contract in the helper's signature so omission cannot compile away
When it happens
Trigger: Calling ScanForSARefs with KeyPath set but omitting context.WithValue(ctx, internal.KeyWait, b); storing a *bool or any non-bool under the key makes the assertion fail identically.
Common situations: Callers copying the ScanForRefs contract (where Wait is optional) into ScanForSARefs; refactors that default wait at the call site instead of the context; tests building minimal contexts.
Related errors
- no benchmark dir found in context
- no path specified in context
- expecting context GVR
- expecting context Path
- no dir in context
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/c525311a47b57419.
Report an issue: GitHub.