Go strconv.ParseInt invalid syntax — Numeric String Rejected
Fix strconv.ParseInt/Atoi invalid syntax errors by matching the parsed base and bit size to the input and trimming whitespace and separators first.
Symptoms
- strconv.Atoi returns the error "invalid syntax" for a value that looks numeric
- Parsing works for small numbers but fails for large ones
- A value from a config or CSV file cannot be converted
Possible causes
- The string contains whitespace, underscores, or thousands separators
- A large value exceeds the bit size of ParseInt with base 10 and bitSize 64, or ParseInt32 is used
- A hexadecimal or "0x" prefixed string is parsed with base 10
Diagnosis steps
Reproduce and capture the error
go run - <<'EOF'
package main
import ("fmt"; "strconv")
func main(){ v, err := strconv.Atoi("1,024"); fmt.Printf("%v %v\n", v, err) }
EOFInterpretation
The returned error is a *NumError whose Err field is ErrSyntax or ErrRange, telling you which class of problem you have.
Check the raw bytes
fmt.Printf("%q\n", raw)Interpretation
The %q verb reveals hidden whitespace such as a non-breaking space or a trailing newline.
Root cause
strconv.ParseInt accepts only an optional sign and digits for the given base; Atoi is ParseInt(s, 10, 0). Any other byte, an out-of-range magnitude, or a base prefix mismatch yields ErrSyntax or ErrRange.
Fix
Trim whitespace, strip separators, choose the base explicitly (base 0 auto-detects 0x/0b prefixes), and pick a bit size that covers your data; use ParseInt with bitSize 64 or big.Int for very large values.
Risk note
Ignoring the error and using the zero value turns bad input into a silent 0, which corrupts downstream math.
Verify the fix
Rerun with the cleaned input and confirm no error and the expected integer; add a table test covering whitespace, hex, and overflow.
Symptoms
This guide profiles the failure behind “Go strconv.ParseInt invalid syntax — Numeric String Rejected”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.
Observed symptoms include:
- strconv.Atoi returns the error “invalid syntax” for a value that looks numeric
- Parsing works for small numbers but fails for large ones
- A value from a config or CSV file cannot be converted
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Reproduce and capture the error
go run - <<'EOF'
package main
import ("fmt"; "strconv")
func main(){ v, err := strconv.Atoi("1,024"); fmt.Printf("%v %v\n", v, err) }
EOF
The returned error is a *NumError whose Err field is ErrSyntax or ErrRange, telling you which class of problem you have.
Step 2: Check the raw bytes
fmt.Printf("%q\n", raw)
The %q verb reveals hidden whitespace such as a non-breaking space or a trailing newline.
Likely contributors, in order of frequency:
- The string contains whitespace, underscores, or thousands separators
- A large value exceeds the bit size of ParseInt with base 10 and bitSize 64, or ParseInt32 is used
- A hexadecimal or “0x” prefixed string is parsed with base 10
Root Cause
strconv.ParseInt accepts only an optional sign and digits for the given base; Atoi is ParseInt(s, 10, 0). Any other byte, an out-of-range magnitude, or a base prefix mismatch yields ErrSyntax or ErrRange.
The Fix
Trim whitespace, strip separators, choose the base explicitly (base 0 auto-detects 0x/0b prefixes), and pick a bit size that covers your data; use ParseInt with bitSize 64 or big.Int for very large values.
Watch out: Ignoring the error and using the zero value turns bad input into a silent 0, which corrupts downstream math.
package main
import (
"fmt"
"strconv"
"strings"
)
func toInt(raw string) (int64, error) {
s := strings.TrimSpace(strings.ReplaceAll(raw, ",", ""))
v, err := strconv.ParseInt(s, 0, 64) // base 0 auto-detects 0x / 0b
if err != nil {
return 0, fmt.Errorf("parse %q: %w", raw, err)
}
return v, nil
}
func main() { fmt.Println(toInt(" 1,024 ")) }
Verify and Prevent
Rerun with the cleaned input and confirm no error and the expected integer; add a table test covering whitespace, hex, and overflow.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.