router-for-me/CLIProxyAPI · critical
failed to parse config file: %w
Error message
failed to parse config file: %w
What it means
The config file was read but gopkg.in/yaml.v3 could not unmarshal it into Config. In optional (cloud deploy) mode a parse failure silently yields an empty config; in normal mode it is fatal here. Typical causes are syntax errors: tabs used for indentation, unquoted special characters, duplicate keys, or truncated files.
Source
Thrown at internal/config/config_load.go:88
cfg.UsageStatisticsEnabled = false
cfg.RedisUsageQueueRetentionSeconds = 60
cfg.DisableCooling = false
cfg.SaveCooldownStatus = false
cfg.TransientErrorCooldownSeconds = 0
cfg.DisableImageGeneration = DisableImageGenerationOff
cfg.WebsocketAuth = true
cfg.Pprof.Enable = false
cfg.Pprof.Addr = DefaultPprofAddr
cfg.RemoteManagement.PanelGitHubRepository = DefaultPanelGitHubRepository
cfg.CredentialInFlight = DefaultCredentialInFlightConfig()
if err = yaml.Unmarshal(data, &cfg); err != nil {
if optional {
// In cloud deploy mode, if YAML parsing fails, return empty config instead of error.
cfgOptional := &Config{CredentialInFlight: DefaultCredentialInFlightConfig()}
cfgOptional.NormalizePluginsConfig()
return cfgOptional, nil
}
return nil, fmt.Errorf("failed to parse config file: %w", err)
}
cfg.CredentialConcurrency = cfg.CredentialConcurrency.WithDefaults()
if errValidate := cfg.CredentialInFlight.Validate(); errValidate != nil {
return nil, errValidate
}
if errValidate := cfg.Codex.LiveMediaRelay.Validate(); errValidate != nil {
return nil, errValidate
}
if errValidate := cfg.ValidateCredentialWeights(); errValidate != nil {
return nil, errValidate
}
// Hash remote management key if plaintext is detected (nested)
// We consider a value to be already hashed if it looks like a bcrypt hash ($2a$, $2b$, or $2y$ prefix).
if cfg.RemoteManagement.SecretKey != "" && !looksLikeBcrypt(cfg.RemoteManagement.SecretKey) {
hashed, errHash := hashSecret(cfg.RemoteManagement.SecretKey)
if errHash != nil {View on GitHub (pinned to 78f0c4079e)
Solutions
- Paste the file into a YAML validator or run 'yamllint config.yaml' — the error offset from yaml.v3 points at the line.
- Replace tabs with spaces, quote values containing ': ' or leading special chars.
- If the file was truncated by a concurrent writer, restore from source control and write configs atomically (write temp + rename).
- Beware optional mode: a silent empty config can mask this error — test parsing explicitly when deploying.
Example fix
# before (tab indentation breaks YAML)
codex:
live-media-relay:
enabled: true
# after (spaces)
codex:
live-media-relay:
enabled: true Defensive patterns
Strategy: validation
Validate before calling
// Dry-parse the config before handing it to the server
func configParses(path string) error {
data, err := os.ReadFile(path)
if err != nil { return err }
var probe map[string]any
return yaml.Unmarshal(data, &probe)
} Prevention
- Run yamllint on config.yaml in CI and before manual edits.
- Never use tabs for YAML indentation; quote values containing ':' or '#'.
- Write config updates atomically (temp file + rename) to avoid truncated reads.
- Remember optional mode silently swallows parse errors as an empty config — parse explicitly when that matters.
When it happens
Trigger: yaml.Unmarshal(data, &cfg) returns an error in non-optional mode — e.g. a tab character in indentation, an unquoted ':' inside a value, mismatched quotes, or the file was edited mid-deploy and is half-written.
Common situations: Hand-edited config introducing tabs; secrets with trailing colons or '#' unquoted; CI writing the file non-atomically; mixing JSON and YAML syntax.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- parse plugin enabled: %w
- parse plugin priority: %w
- decode codex.live-media-relay.allow-private-remote-ips: %w
- decode codex.live-media-relay.disable-private-remote-ips: %w
- failed to read config file: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/efced1caf432a124.
Report an issue: GitHub.