derailed/k9s · error
plugin validation failed for %s: %w
Error message
plugin validation failed for %s: %w
What it means
Plugins.load (internal/config/plugin.go:158-165) first runs the plugin file through data.JSONValidator.ValidatePlugins, which validates the document against k9s's bundled JSON schemas and detects which of the three supported shapes it is (plugin / plugins map / plugins list). This error wraps that schema failure with the offending file path; the raw validation detail is also logged as a slog.Warn with slogs.Path and slogs.Error.
Source
Thrown at internal/config/plugin.go:164
return errs
}
func (p *Plugins) load(path string) error {
if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) {
return nil
}
bb, err := os.ReadFile(path)
if err != nil {
return err
}
scheme, err := data.JSONValidator.ValidatePlugins(bb)
if err != nil {
slog.Warn("Plugin schema validation failed",
slogs.Path, path,
slogs.Error, err,
)
return fmt.Errorf("plugin validation failed for %s: %w", path, err)
}
d := yaml.NewDecoder(bytes.NewReader(bb))
d.KnownFields(true)
switch scheme {
case json.PluginSchema:
var o Plugin
if err := yaml.Unmarshal(bb, &o); err != nil {
return fmt.Errorf("plugin unmarshal failed for %s: %w", path, err)
}
if err := o.Validate(); err != nil {
return fmt.Errorf("plugin validation failed for %s: %w", path, err)
}
p.Plugins[strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))] = o
case json.PluginsSchema:
var oo Plugins
if err := yaml.Unmarshal(bb, &oo); err != nil {View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Run k9s from a terminal and read the slog.Warn line immediately preceding the returned error - it carries the exact schema violation
- Fix the file so it matches one of the three supported shapes: a single plugin object, a `plugins:` map keyed by name, or a `plugins:` list
- Correct field names/casing (shortCut, command, description, scopes) against the bundled schema
- If the file is not meant for k9s, remove it from the plugins directory ($XDG_CONFIG_HOME/k9s/plugins, XDG data dirs, or the context config path)
Example fix
# before (unknown key, missing shortCut) shortcut: e description: edit command: vim # after shortCut: e description: edit command: vim
Defensive patterns
Strategy: validation
Validate before calling
// Smoke-test a plugin file before dropping it into k9s's config dirs:
// it must parse as YAML and carry only known top-level keys.
var knownKeys = map[string]bool{"shortCut":true,"description":true,"command":true,"scopes":true,"args":true,"override":true,"pipes":true,"confirm":true,"background":true,"dangerous":true,"overwriteOutput":true,"inputs":true,"plugins":true}
func LintPluginFile(path string) error {
b, err := os.ReadFile(path)
if err != nil { return err }
var m map[string]any
if err := yaml.Unmarshal(b, &m); err != nil { return err }
for k := range m {
if !knownKeys[k] { return fmt.Errorf("unknown key %q in %s", k, path) }
}
return nil
} Prevention
- Pin plugin files to one of the three supported shapes: single plugin, plugins map, plugins list
- Run k9s once from a terminal after every plugin edit and read the slog.Warn schema detail
- Keep plugin files out of XDG data dirs until they lint clean
When it happens
Trigger: A plugin file whose top-level keys do not match any supported schema: unknown fields, missing required fields (shortCut, command, description), wrong types (scopes not a string list), or a document that mixes the single-plugin and map forms. It aborts before any yaml.Unmarshal of the plugin body runs.
Common situations: Upgrading k9s where the plugin schema gained/renamed required fields; typos in top-level keys (e.g. shortcut vs shortCut); using a plugin written for another tool or an older k9s version; extra XDG data-dir plugin files shipping with a distribution.
Related errors
- default value %q for number input %q is not a valid number
- plugin %q validation failed for %s: %w
- plugin unmarshal failed for %s: %w
- k9s config file %q load failed: %w
- duplicate input name %q
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/7fdfb0c29e3a087a.
Report an issue: GitHub.