fatedier/frp · error
toml: line %d, column %d: %s
Error message
toml: line %d, column %d: %s
What it means
When a TOML frp config file fails to decode, formatTOMLError converts the pelletier/go-toml DecodeError into a message with 1-indexed line and column of the offending syntax plus the parser's description. This gives precise locations for structural TOML errors (bad brackets, duplicate keys, invalid values).
Source
Thrown at pkg/config/load.go:224
// Handle YAML content
if strict {
// In strict mode, always use our custom handler to support YAML merge
if err := parseYAMLWithDotFieldsHandling(b, c); err != nil {
return enhanceDecodeError(err, originalBytes, !parsedFromTOML)
}
return nil
}
// Non-strict mode, parse normally
return yaml.Unmarshal(b, c)
}
// formatTOMLError extracts line/column information from TOML decode errors.
func formatTOMLError(err error) error {
var decErr *toml.DecodeError
if errors.As(err, &decErr) {
row, col := decErr.Position()
return fmt.Errorf("toml: line %d, column %d: %s", row, col, decErr.Error())
}
var strictErr *toml.StrictMissingError
if errors.As(err, &strictErr) {
return strictErr
}
return err
}
// enhanceDecodeError tries to add field path and line number information to JSON/YAML decode errors.
func enhanceDecodeError(err error, originalContent []byte, includeLine bool) error {
var typeErr *json.UnmarshalTypeError
if errors.As(err, &typeErr) && typeErr.Field != "" {
if includeLine {
line := findFieldLineInContent(originalContent, typeErr.Field)
if line > 0 {
return fmt.Errorf("line %d: field \"%s\": cannot unmarshal %s into %s", line, typeErr.Field, typeErr.Value, typeErr.Type)
}
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Go to the reported line:column and fix the syntax pointed at
- Run a TOML linter (taplo, toml-validate) over the file
- If the file is actually YAML/JSON, rename it with the proper extension so frp picks the right parser
Example fix
# before (line 12 reported) [[proxies] name = "web" # after [[proxies]] name = "web"
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate TOML before loading
if err := toml.Unmarshal(raw, map[string]any{}); err != nil { return fmt.Errorf("toml pre-check: %w", err) } Try / catch
if err := config.LoadConfigureFromFile(path, &cfg, strict); err != nil { var decErr *toml.DecodeError; if errors.As(err, &decErr) { r, c := decErr.Position(); /* point editor at r:c */ } } Prevention
- Use a TOML-aware editor (taplo/inlay hints)
- Run toml lint in CI
- Keep YAML snippets out of .toml files
When it happens
Trigger: Loading a .toml frpc/frps config whose syntax is invalid: unclosed table [[proxies]], duplicate key in one table, wrong scalar syntax, stray characters. The TOML unmarshal path in LoadConfigureFromFile routes through this formatter.
Common situations: Hand-editing TOML configs and losing a bracket; snippets pasted from YAML docs into TOML files (colons/indentation); TOML files written by scripts with unescaped strings.
Related errors
- line %d: field "%s": cannot unmarshal %s into %s
- field "%s": cannot unmarshal %s into %s
- load additional config from %s error: %v
- failed to parse JSON: %w
- range number is invalid, %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/cf8876aa022b03e0.
Report an issue: GitHub.