router-for-me/CLIProxyAPI · error
parse plugin enabled: %w
Error message
parse plugin enabled: %w
What it means
Thrown while decoding the 'enabled' field of a plugin instance in config.yaml. PluginInstanceConfig uses a custom UnmarshalYAML that walks the yaml.Node pair-by-pair; when the value under the 'enabled' key cannot be decoded into a Go bool, this wrapped error is returned. The %w chain carries the underlying gopkg.in/yaml.v3 type error (e.g. 'cannot unmarshal !!str into bool').
Source
Thrown at internal/config/config_types.go:67
return nil
}
c.Raw = *deepCopyNode(value)
if value.Kind != yaml.MappingNode {
return nil
}
for i := 0; i+1 < len(value.Content); i += 2 {
key := value.Content[i]
node := value.Content[i+1]
if key == nil {
continue
}
switch key.Value {
case "enabled":
var enabled bool
if errDecodeEnabled := node.Decode(&enabled); errDecodeEnabled != nil {
return fmt.Errorf("parse plugin enabled: %w", errDecodeEnabled)
}
c.Enabled = &enabled
case "priority":
var priority int
if errDecodePriority := node.Decode(&priority); errDecodePriority != nil {
return fmt.Errorf("parse plugin priority: %w", errDecodePriority)
}
c.Priority = priority
}
}
return nil
}
// MarshalYAML returns the preserved raw plugin YAML subtree for lossless config output.
func (c PluginInstanceConfig) MarshalYAML() (any, error) {
if c.Raw.Kind == 0 {
return defaultPluginInstanceConfigNode(), nilView on GitHub (pinned to 78f0c4079e)
Solutions
- Open config.yaml, find the plugins section, and set enabled to a bare true or false (unquoted).
- Remove quotes around the value: change enabled: "true" to enabled: true.
- If the value was 'yes'/'no'/'on'/'off'/'1'/'0', replace it with true/false.
- Validate the file with a YAML parser or 'go run ./cmd/server --config config.yaml' before deploying.
- If you generate the config programmatically, ensure the field is emitted as a bool, not a string.
Example fix
# before (config.yaml)
plugins:
configs:
myplugin:
enabled: "yes"
# after
plugins:
configs:
myplugin:
enabled: true Defensive patterns
Strategy: validation
Validate before calling
// Go: verify plugin enabled values are plain booleans before loading config.
import (
"os"
"gopkg.in/yaml.v3"
)
func pluginEnabledValid(path string) (bool, error) {
data, err := os.ReadFile(path)
if err != nil {
return false, err
}
var root map[string]any
if err := yaml.Unmarshal(data, &root); err != nil {
return false, err
}
plugins, ok := root["plugins"].(map[string]any)
if !ok {
return true, nil // no plugins section
}
walkConfigs(plugins) // check every "enabled" under plugins.configs.*
return true, nil
}
func walkConfigs(m map[string]any) {
for _, v := range m {
if inst, ok := v.(map[string]any); ok {
if enabled, exists := inst["enabled"]; exists {
if _, isBool := enabled.(bool); !isBool {
panic("plugin enabled must be a bare true/false")
}
}
}
}
} Prevention
- Always write enabled: true/false unquoted in config.yaml.
- Never use yes/no/on/off/1/0 for booleans — YAML 1.2 keeps them as strings.
- Run a YAML schema lint on config.yaml in CI.
- Avoid saving config mid-edit when the hot-reload watcher is active.
When it happens
Trigger: A plugins: section in config.yaml where a plugin instance sets enabled to a non-boolean, e.g. 'plugins:\n configs:\n myplugin:\n enabled: "yes"' or 'enabled: 1' or 'enabled: on/off' (YAML 1.2 core schema does not coerce these strings to bool). Also triggered by an empty scalar '~' or a nested map under 'enabled'.
Common situations: Copying a plugin block from documentation that used quoted strings; migrating from a config format that accepted 'yes'/'no'; editing config.yaml by hand while the file watcher hot-reloads a half-finished edit; using a YAML linter that auto-quotes booleans as strings.
Related errors
- parse plugin priority: %w
- failed to parse config file: %w
- decode codex.live-media-relay.allow-private-remote-ips: %w
- decode codex.live-media-relay.disable-private-remote-ips: %w
- invalid yaml document structure
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/fcc98ed3dde1b250.
Report an issue: GitHub.