antonmedv/fx · error
Invalid character %q in number
Error message
Invalid character %q in number
What it means
parseMinus consumed a leading '-' but the next character is neither a digit nor (in non-strict mode) n/N (NaN) or i/I (Infinity). A negative number must be followed by a digit, so the parser panics reporting the offending character.
Source
Thrown at internal/jsonx/json.go:267
return str
}
func (p *JsonParser) parseMinus() *Node {
start := p.end - 1
p.next()
switch p.char {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return p.parseNumber(start)
}
if !p.strict {
switch p.char {
case 'n', 'N':
return p.parseNan(start)
case 'i', 'I':
return p.parseInfinity(start)
}
}
panic(fmt.Sprintf("Invalid character %q in number", p.char))
}
func (p *JsonParser) parseNumber(start int) *Node {
num := &Node{
Kind: Number,
Depth: p.depth,
LineNumber: p.lineNumberPlusPlus(),
}
// Leading zero
if p.char == '0' {
p.next()
} else {
for utils.IsDigit(p.char) {
p.next()
}
}
View on GitHub (pinned to 4f31cd3a0c)
Solutions
- Replace the bare '-' with a valid negative number (e.g. -1) or null
- If the intent was -Infinity or -NaN, disable strict mode so parseMinus accepts n/N and i/I
- Validate numeric fields before serialization so empty values become null instead of '-'
- Locate the exact position via the %q character in the message and repair that line
Example fix
// before
{"delta": -}
// after
{"delta": -1} // or null; or use -Infinity with strict=false Defensive patterns
Strategy: validation
Validate before calling
// Reject bare '-' before parsing
for _, m := range bareMinus.FindAllString(string(b), -1) { // regexp: `(-)([^0-9]|$)`
_ = m
return errors.New("minus sign not followed by digit or -Infinity")
} Try / catch
defer func() {
if r := recover(); r != nil {
if msg, ok := r.(string); ok && strings.Contains(msg, "in number") {
err = fmt.Errorf("malformed negative number: %s", msg)
}
}
}() Prevention
- Validate numeric fields at serialization time (never emit bare '-')
- Map unknown numerics to null instead of placeholders
- Use -Infinity only with strict=false and document it
- Sanitize templated numbers so empty variables become null
When it happens
Trigger: Parse on inputs like `-,`, `-}`, `- abc`, `"key": -` , or `-NaN`/`-Infinity` while strict mode is enabled (the lenient branch is skipped when p.strict is true).
Common situations: Hand-edited numeric fields left as bare '-', JavaScript payloads with -Infinity parsed in strict mode, template rendering producing `"timeout": -` when a variable was empty, CSV/JSON converters emitting placeholder minus signs.
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
- Invalid escape sequence '\%c'
- Invalid Unicode escape sequence '\u%s%c'
- Expected object key to be a string, got %q
- Expected colon after object key, got %q
- Trailing comma is not allowed in strict mode
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/54c34bf641ab05be.
Report an issue: GitHub.