derailed/k9s · error

no screendump dir found in context

Error message

no screendump dir found in context

What it means

ScreenDump.List lists the .png files k9s writes when you take screen captures; the directory is taken from ctx.Value(internal.KeyDir), which view/screen_dump.go:45 sets from the configured screen-dump dir. If the DAO is called with a context lacking that key, there is no directory to read and the call fails before os.ReadDir.

Source

Thrown at internal/dao/screen_dump.go:36

	_ Accessor = (*ScreenDump)(nil)
	_ Nuker    = (*ScreenDump)(nil)
)

// ScreenDump represents a scraped resources.
type ScreenDump struct {
	NonResource
}

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

// List returns a collection of screen dumps.
func (*ScreenDump) List(ctx context.Context, _ string) ([]runtime.Object, error) {
	dir, ok := ctx.Value(internal.KeyDir).(string)
	if !ok {
		return nil, errors.New("no screendump dir found in context")
	}

	ff, err := os.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	oo := make([]runtime.Object, len(ff))
	for i, f := range ff {
		if fi, err := f.Info(); err == nil {
			oo[i] = render.FileRes{File: fi, Dir: dir}
		}
	}

	return oo, nil
}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Inject the dir before listing: ctx = context.WithValue(ctx, internal.KeyDir, dir) mirroring internal/view/screen_dump.go:45.
  2. Derive the dir from configuration the same way the shipped view does (screen dump dir from config), so it points at where captures are actually written.
  3. For tests, seed the context like dao/benchmark_test.go:22 does with KeyDir.

Example fix

// before
oo, err := sd.List(context.Background(), "") // -> no screendump dir found in context
// after
dir := cfg.ScreenDumpDir()
ctx := context.WithValue(context.Background(), internal.KeyDir, dir)
oo, err := sd.List(ctx, "")
Defensive patterns

Strategy: validation

Validate before calling

if _, ok := ctx.Value(internal.KeyDir).(string); !ok {
    ctx = context.WithValue(ctx, internal.KeyDir, cfg.ScreenDumpDir())
}
oo, err := screenDumpDAO.List(ctx, "")

Type guard

func dirFromCtx(ctx context.Context) (string, bool) {
    d, ok := ctx.Value(internal.KeyDir).(string)
    return d, ok
}

Prevention

When it happens

Trigger: Calling dao ScreenDump.List with a bare context (no context.WithValue(ctx, internal.KeyDir, dir)); storing a non-string under KeyDir.

Common situations: Unit/integration tests or custom code driving the DAO directly; a custom view that replicates the screen-dump browser but forgets the dir injection; renaming the ContextKey so producer and consumer disagree.

Related errors


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