derailed/k9s · error
plugin unmarshal failed for %s: %w
Error message
plugin unmarshal failed for %s: %w
What it means
After schema validation succeeds for the single-plugin shape (json.PluginSchema), Plugins.load yaml.Unmarshals the bytes into the Plugin struct (internal/config/plugin.go:171-173). This error wraps a YAML decode/type failure specific to that struct.
Source
Thrown at internal/config/plugin.go:174
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 {
return fmt.Errorf("plugin unmarshal failed for %s: %w", path, err)
}
for k := range oo.Plugins {
plug := oo.Plugins[k]
if err := plug.Validate(); err != nil {
return fmt.Errorf("plugin %q validation failed for %s: %w", k, path, err)
}
p.Plugins[k] = plug
}
case json.PluginMultiSchema:View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Run the file through a YAML linter (yamllint) or `python -c 'import yaml,sys; yaml.safe_load(open(sys.argv[1]))' file.yml`
- Fix indentation (spaces only), remove duplicate keys and smart quotes
- Simplify: remove anchors/merge keys and inline the values
- The wrapped error text names the YAML line/type at fault - read the %w tail
Defensive patterns
Strategy: validation
Validate before calling
// Strict-decode a plugin file the way k9s nearly does (decoder with KnownFields)
// to surface type/indent errors before launch.
func StrictLint(path string) error {
b, _ := os.ReadFile(path)
d := yaml.NewDecoder(bytes.NewReader(b))
d.KnownFields(true)
var o config.Plugin
return d.Decode(&o)
} Prevention
- Use spaces, never tabs, in plugin YAML
- yamllint every plugin file in CI
- Avoid anchors/merge keys in config consumed by Go yaml.v3
When it happens
Trigger: YAML that passes the JSON-schema check but still fails decoding into Plugin: duplicate YAML keys, tab indentation errors, unexpected anchors/aliases, or scalars that cannot coerce into the string/bool fields (e.g. `dangerous: yes-please`). Note this path uses yaml.Unmarshal (not the KnownFields decoder built at plugin.go:168-169), so unknown fields alone do not trigger it.
Common situations: Hand-edited plugin files with tabs instead of spaces; copy-paste from websites introducing smart quotes or duplicate keys; YAML anchors left over from templating.
Related errors
- default value %q for number input %q is not a valid number
- plugin validation failed for %s: %w
- plugin %q validation failed for %s: %w
- main config.yaml load failed: %w
- k9s config file %q load failed: %w
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/532375b58ae5b79d.
Report an issue: GitHub.