antonmedv/fx · error
Trailing comma is not allowed in strict mode
Error message
Trailing comma is not allowed in strict mode
What it means
The parser tolerates trailing commas in non-strict mode, but in strict mode (JsonParser created with strict=true) a comma immediately before a closing '}' is rejected. Before panicking, it rewinds the parser position back to the comma (p.set(commaPos)) so the reported location points at the trailing comma. Strict mode follows the JSON RFC, which forbids trailing commas.
Source
Thrown at internal/jsonx/json.go:369
value := p.parseValue(false)
value.Key = keyBytes
value.Parent = object
p.depth--
object.Append(value)
object.Size += 1
p.skipWhitespace()
commaPos := p.end
if p.char == ',' {
object.End.Comma = true
p.next()
p.skipWhitespace()
if p.char == '}' {
if p.strict {
p.set(commaPos)
panic("Trailing comma is not allowed in strict mode")
}
object.End.Comma = false
} else {
continue
}
}
if p.char == '}' {
closeBracket := &Node{
Kind: Object,
Depth: p.depth,
LineNumber: p.lineNumberPlusPlus(),
}
closeBracket.Value = curlyBracketClose
closeBracket.Parent = object
closeBracket.Index = -1
object.Append(closeBracket)
p.next()View on GitHub (pinned to 4f31cd3a0c)
Solutions
- Remove the trailing comma before the closing brace: {"a":1,} -> {"a":1}
- If trailing commas are acceptable for your use case, parse in non-strict mode instead of strict mode
- Normalize the input before parsing (strip ',}' / ',]' sequences)
Example fix
// before (strict parse)
{"a": 1, "b": 2,}
// after
{"a": 1, "b": 2} Defensive patterns
Strategy: validation
Validate before calling
func stripTrailingCommas(src []byte) []byte {
// lenient preprocessor: remove ',}' and ',]' outside strings (strict-mode input)
out := make([]byte, 0, len(src))
inStr, esc := false, false
for i := 0; i < len(src); i++ {
c := src[i]
if esc { esc = false; out = append(out, c); continue }
if c == '\\' && inStr { esc = true; out = append(out, c); continue }
if c == '"' { inStr = !inStr; out = append(out, c); continue }
if !inStr && c == ',' {
j := i + 1
for j < len(src) && (src[j]==' '||src[j]=='\t'||src[j]=='\n'||src[j]=='\r') { j++ }
if j < len(src) && (src[j] == '}' || src[j] == ']') { continue }
}
out = append(out, c)
}
return out
} Try / catch
func parseStrictLenient(p *jsonx.JsonParser, data []byte) (root *jsonx.Node, err error) {
defer func() {
if r := recover(); r != nil {
if strings.Contains(fmt.Sprint(r), "Trailing comma") {
// fallback: retry after stripping trailing commas
defer func() { recover() }()
root = jsonx.NewParser(jsonx.WithStrict(false)).Parse(stripTrailingCommas(data))
return
}
err = fmt.Errorf("json parse failed: %v", r)
}
}()
root = p.Parse(data)
return
} Prevention
- Decide strict vs lenient mode once at app level and document it
- If consuming JS-derived JSON, either disable strict mode or strip trailing commas first
- Configure linters/prettier on JSON files with "trailingComma": "none"
- Strip trailing commas in a preprocessing step before strict parsing
When it happens
Trigger: Parsing {"a":1,} or {"a":1, } with strict mode enabled (e.g. ParseStrict-style APIs or parser configured with strict: true).
Common situations: JSON copied from JavaScript source or ESLint/Prettier-formatted code where trailing commas are stylistic; build tools emitting JS-flavored JSON; hand-edited config where an entry was deleted leaving a dangling comma.
Related errors
- Invalid Unicode escape sequence '\u%s%c'
- Invalid escape sequence '\%c'
- Invalid character %q in number
- Comments are not allowed in strict mode
- Invalid Unicode escape sequence '\u%s'
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/5489440f363fecfb.
Report an issue: GitHub.