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

  1. Fix or normalize the log format so the parsed field contains only digits.
  2. Pre-validate the field with a digit-only check before calling atoi.
  3. Replace atoi with strconv.Atoi (or ParseFloat) if negatives/floats must be supported.
  4. 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

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


AI-assisted analysis of inancgumus/learngo@3c475a78e5 (2026-09-02). Data as JSON: /api/errors/39400719be0b32a6. Report an issue: GitHub.