derailed/k9s · error

expecting a switchable resource

Error message

expecting a switchable resource

What it means

Returned by `useContext` (internal/view/context.go:~156), the handler for `:use <ctx>`. Exactly like the contextCmd path, it loads the DAO for `client.CtGVR` and asserts `dao.Switchable`; if the registered accessor lacks that interface the switch is aborted before the config is saved. In upstream k9s this cannot happen — the contexts DAO implements Switchable — so hitting it means a customized/broken DAO factory.

Source

Thrown at internal/view/context.go:156

		app.Flash().Err(err)
		return
	}
	c.App().clearHistory()
	c.Refresh()
	c.GetTable().Select(1, 0)
}

func useContext(app *App, name string) error {
	if app.Content.Top() != nil {
		app.Content.Top().Stop()
	}
	res, err := dao.AccessorFor(app.factory, client.CtGVR)
	if err != nil {
		return err
	}
	switcher, ok := res.(dao.Switchable)
	if !ok {
		return errors.New("expecting a switchable resource")
	}

	app.Config.K9s.ToggleContextSwitch(true)
	defer app.Config.K9s.ToggleContextSwitch(false)

	// Save config prior to context switch...
	if err := app.Config.Save(true); err != nil {
		slog.Error("Fail to save config to disk", slogs.Subsys, "config", slogs.Error, err)
	}

	if err := switcher.Switch(name); err != nil {
		slog.Error("Context switch failed during use command", slogs.Error, err)
		return err
	}

	return app.switchContext(cmd.NewInterpreter("ctx "+name), true)
}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Restore/register the stock contexts DAO that implements dao.Switchable for client.CtGVR
  2. In forks, implement Switch(ctx string) error on the custom contexts accessor
  3. Alternatively switch contexts via KUBECONFIG + `--context` flag as a workaround while the factory is fixed
Defensive patterns

Strategy: type-guard

Type guard

func switchableFor(f dao.Factory) (dao.Switchable, error) {
    a, err := dao.AccessorFor(f, client.CtGVR)
    if err != nil {
        return nil, err
    }
    s, ok := a.(dao.Switchable)
    if !ok {
        return nil, errors.New("expecting a switchable resource")
    }
    return s, nil
}

Try / catch

switcher, err := switchableFor(app.factory)
if err != nil { return err }
return switcher.Switch(name)

Prevention

When it happens

Trigger: Running `:use <context>` (or clicking through the context view) while the factory resolves client.CtGVR to an accessor that does not implement dao.Switchable.

Common situations: Forked builds or plugins replacing the contexts DAO; mocked factories in tests; version mismatch between internal packages after a partial upgrade.

Related errors


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