inancgumus/learngo · error
invalid number
Error message
invalid number
What it means
atoi() is a hand-rolled byte-to-int parser used by fastParseFields; it only accepts ASCII digits 0-9. Any non-digit byte in the input causes it to abandon parsing and return "invalid number" with a zero value.
Source
Thrown at logparser/functional/field.go:36
type field struct{ err error }
// uatoi parses an unsigned integer string and saves the error.
// it assumes that the val is unsigned.
// for ease of usability: it returns an int instead of uint.
func (f *field) uatoi(name, val string) int {
n, err := strconv.Atoi(val)
if err != nil || n < 0 {
f.err = fmt.Errorf("incorrect field -> %q = %q", name, val)
}
return n
}
func atoi(input []byte) (int, error) {
val := 0
for i := 0; i < len(input); i++ {
char := input[i]
if char < '0' || char > '9' {
return 0, errors.New("invalid number")
}
val = val*10 + int(char) - '0'
}
return val, nil
}
View on GitHub (pinned to 3c475a78e5)
Solutions
- Fix or normalize the log format so the parsed field contains only digits.
- Pre-validate the field with a digit-only check before calling atoi.
- Replace atoi with strconv.Atoi (or ParseFloat) if negatives/floats must be supported.
- Skip or quarantine malformed records instead of failing the whole parse.
Example fix
// before val = val*10 + int(char) - '0' // after (support negatives/robustness) return strconv.Atoi(string(input))
Defensive patterns
Strategy: validation
Validate before calling
func isDigits(b []byte) bool {
if len(b) == 0 { return false }
for _, c := range b {
if c < '0' || c > '9' { return false }
}
return true
}
if !isDigits(field) { skipRecord() } Type guard
func isNumericField(b []byte) bool {
for _, c := range b {
if c < '0' || c > '9' { return false }
}
return len(b) > 0
} Try / catch
n, err := atoi(field)
if err != nil {
if err.Error() == "invalid number" {
log.Printf("skipping non-numeric field %q", field)
return 0, nil // or propagate
}
return 0, err
} Prevention
- Validate the log format with a schema or golden-file test before parsing
- Trim and check each column before numeric conversion
- Prefer strconv.Atoi for inputs that may include signs or leading whitespace
- Quarantine malformed lines instead of aborting the whole parse
When it happens
Trigger: fastParseFields passes a field byte-slice containing any character outside '0'-'9' to atoi — e.g. a log field like "12.5", "-3", "1e2", "0x10", "12a", or an empty/non-numeric token.
Common situations: Parsing log lines where the expected numeric column holds N/A, floats, signed numbers, or misaligned columns due to a changed log format or separator.
Related errors
- record.domain cannot be empty
- record.page cannot be empty
- record.visits cannot be negative
- record.uniques cannot be negative
- record.domain cannot be empty|record.page cannot be empty|re
AI-assisted analysis of inancgumus/learngo@3c475a78e5 (2026-09-02).
Data as JSON: /api/errors/39400719be0b32a6.
Report an issue: GitHub.