inancgumus/learngo · error

missing fields

Error message

missing fields: %v

What it means

parse splits a log line with strings.Fields and requires exactly 3 fields: domain, visits, and time spent. Any other count returns this error listing the fields actually found, signaling the line doesn't match the expected 'domain visits timespent' format.

Solutions

  1. Normalize the input so every line has exactly: domain visits timeSpent
  2. Skip empty/whitespace-only lines before calling parse
  3. Give a clearer message, e.g. expected 3 fields, got N, with the raw line

Example fix

// before
if len(fields) != 3 {
    return r, fmt.Errorf("missing fields: %v", fields)
}
// after
if len(fields) != 3 {
    return r, fmt.Errorf("expected 3 fields (domain visits timeSpent), got %d: %q", len(fields), line)
}
Defensive patterns

Strategy: validation

Validate before calling

func validResultLine(line string) bool {
    fs := strings.Fields(line)
    return len(fs) == 3
}
// call before parse: if !validResultLine(line) { skip }

Type guard

func hasThreeFields(line string) bool {
    return len(strings.Fields(line)) == 3
}

Try / catch

r, err := parse(line)
if err != nil {
    if strings.HasPrefix(err.Error(), "missing fields") {
        log.Printf("skipping malformed line %q: %v", line, err)
        continue
    }
    return err
}

Prevention

When it happens

Trigger: Calling parse (from main, via the report parser) with a line containing 0, 1, 2, or 4+ whitespace-separated tokens, e.g. a blank line or a line missing the time-spent value.

Common situations: Hand-edited log files, CSV/TSV lines pasted into a space-separated log, trailing multi-space entries that Fields collapses, or header/footer lines in exported logs.

Related errors


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

Appendix: source

Thrown at logparser/testing/report/result.go:42

	Visits    int    `json:"visits"`
	TimeSpent int    `json:"time_spent"`
	// add more metrics if needed
}

// add adds the metrics of another Result to itself and returns a new Result
func (r Result) add(other Result) Result {
	return Result{
		Domain:    r.Domain,
		Visits:    r.Visits + other.Visits,
		TimeSpent: r.TimeSpent + other.TimeSpent,
	}
}

// parse parses a single log line
func parse(line string) (r Result, err error) {
	fields := strings.Fields(line)
	if len(fields) != 3 {
		return r, fmt.Errorf("missing fields: %v", fields)
	}

	f := new(field)
	r.Domain = fields[0]
	r.Visits = f.atoi("visits", fields[1])
	r.TimeSpent = f.atoi("time spent", fields[2])
	return r, f.err
}

// field helps for field parsing
type field struct{ err error }

func (f *field) atoi(name, val string) int {
	n, err := strconv.Atoi(val)
	if n < 0 || err != nil {
		f.err = fmt.Errorf("incorrect %s: %q", name, val)
	}
	return n

View on GitHub (pinned to 3c475a78e5)