derailed/k9s · error

expecting screendumper, but got %T

Error message

expecting screendumper, but got %T

What it means

ScreenDump.Render lists screen-dump files and requires a render.FileRes value — {File os.FileInfo, Dir string} — which the screendumps browser builds from directory scans. The comma-ok assertion matches the value type, so a *FileRes pointer, a bare os.FileInfo, or any other payload fails with this error printing the concrete %T.

Source

Thrown at internal/render/screen_dump.go:45

		return tcell.ColorNavajoWhite
	}
}

// Header returns a header row.
func (ScreenDump) Header(string) model1.Header {
	return model1.Header{
		model1.HeaderColumn{Name: "NAME"},
		model1.HeaderColumn{Name: "DIR"},
		model1.HeaderColumn{Name: "VALID", Attrs: model1.Attrs{Wide: true}},
		model1.HeaderColumn{Name: "AGE", Attrs: model1.Attrs{Time: true}},
	}
}

// Render renders a K8s resource to screen.
func (ScreenDump) Render(o any, _ string, r *model1.Row) error {
	f, ok := o.(FileRes)
	if !ok {
		return fmt.Errorf("expecting screendumper, but got %T", o)
	}

	r.ID = filepath.Join(f.Dir, f.File.Name())
	r.Fields = model1.Fields{
		f.File.Name(),
		f.Dir,
		"",
		timeToAge(f.File.ModTime()),
	}

	return nil
}

// ----------------------------------------------------------------------------
// Helpers...

func timeToAge(timestamp time.Time) string {
	return duration.HumanDuration(time.Since(timestamp))

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Pass render.FileRes by value (FileRes{File: info, Dir: dir})
  2. Bind the ScreenDump renderer only to the screendumps view
  3. Use the comma-ok form in wrappers and skip mismatches
  4. Log the %T from the error to find the offending producer

Example fix

// before
err := sdRenderer.Render(&render.FileRes{File: info, Dir: dir}, ns, row)
// after
err := sdRenderer.Render(render.FileRes{File: info, Dir: dir}, ns, row)
Defensive patterns

Strategy: type-guard

Validate before calling

// gate before invoking the screendumps renderer
if _, ok := o.(render.FileRes); !ok {
	return fmt.Errorf("screendumps view requires render.FileRes value, got %T", o)
}
err := sdRenderer.Render(o, ns, row)

Type guard

func isFileRes(o any) bool {
	_, ok := o.(render.FileRes)
	return ok
}

Try / catch

if err := sdRenderer.Render(o, ns, row); err != nil {
	slog.Warn("screendump row skipped", "type", fmt.Sprintf("%T", o), slogs.Error, err)
	return nil // drop the row, keep the view alive
}

Prevention

When it happens

Trigger: Calling ScreenDump{}.Render with &FileRes{...}, an os.FileInfo alone, or a path string; custom views reusing the screendumps renderer for non-file rows; refactors that change the file walker's output type.

Common situations: Adding plugins that list local files as resources; changing where screen dumps are stored and the walker that enumerates them; test fixtures using pointers.

Related errors


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