Billionmail/BillionMail · warning

end_date must not be before start_date

Error message

end_date must not be before start_date

What it means

getLogFilesInRange builds the list of operation-log .log files between start_date and end_date. Before scanning, it validates the parsed dates and rejects any range whose end precedes its start. This guards the day-iteration loop, which would otherwise produce zero files silently.

Source

Thrown at core/internal/controller/operation_log/operation_log_v1_get_output_log.go:120

	for i, j := 0, len(lines)-1; i < j; i, j = i+1, j-1 {
		lines[i], lines[j] = lines[j], lines[i]
	}
}

func getLogFilesInRange(ctx context.Context, start, end string) ([]string, error) {
	logDir := public.AbsPath("../logs/core/out")
	layout := "2006-01-02"

	startDate, err := time.Parse(layout, start)
	if err != nil {
		return nil, fmt.Errorf("invalid start_date: %v", err)
	}
	endDate, err := time.Parse(layout, end)
	if err != nil {
		return nil, fmt.Errorf("invalid end_date: %v", err)
	}
	if endDate.Before(startDate) {
		return nil, fmt.Errorf("end_date must not be before start_date")
	}

	var files []string

	for d := startDate; !d.After(endDate); d = d.AddDate(0, 0, 1) {
		fname := filepath.Join(logDir, d.Format("2006-01-02")+".log")
		if _, err := os.Stat(fname); err == nil {
			files = append(files, fname)
		}
	}

	if len(files) == 0 {
		return nil, fmt.Errorf("no log files found")
	}
	return files, nil
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Correct the request so end_date is on or after start_date
  2. Swap the parameters if they were accidentally reversed
  3. Add client-side validation in the date picker to prevent submitting inverted ranges
  4. If the intent was 'most recent logs', pass only end_date and let defaults apply, or set start_date earlier

Example fix

// before
GET /api/v1/operation-log/output?start_date=2026-09-05&end_date=2026-09-01
// after
GET /api/v1/operation-log/output?start_date=2026-09-01&end_date=2026-09-05
Defensive patterns

Strategy: validation

Validate before calling

const s = new Date(startDate), e = new Date(endDate);
if (isNaN(s) || isNaN(e)) throw new Error('invalid date');
if (e < s) throw new Error('end_date must not be before start_date');

Type guard

function isValidRange(start: string, end: string): boolean {
  const s = new Date(start), e = new Date(end);
  return !isNaN(s.getTime()) && !isNaN(e.getTime()) && e >= s;
}

Try / catch

try {
  const files = await api.getOutputLog({ start_date, end_date });
} catch (err) {
  if (String(err.message).includes('end_date must not be before start_date')) {
    // swap or prompt user to fix the range
  }
}

Prevention

When it happens

Trigger: Calling GetOutputLog with end_date earlier than start_date, e.g. start_date=2026-09-05&end_date=2026-09-01, or swapped/mistyped date strings that still parse via time.Parse.

Common situations: Frontend date-range pickers letting users select an inverted range; clients passing parameters in wrong order; timezone-related off-by-one where 'today' is computed differently on client and server; API consumers reusing a saved end date after the start date was updated.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/77b5099233aedb45. Report an issue: GitHub.