← Debugging Guides

阅读中文版本

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.

beginnerdebugginggostrconvparsing

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) }
EOF

Interpretation

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.