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
- Correct the request so end_date is on or after start_date
- Swap the parameters if they were accidentally reversed
- Add client-side validation in the date picker to prevent submitting inverted ranges
- 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
- Use a date-range picker that enforces end >= start
- Validate the range client-side before the API call
- Store dates in a single canonical format/timezone
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
- No log files found in the given date range
- required column 'email' not found
- You cannot create more than 5000 batches
- invalid start_date: %v
- invalid end_date: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/77b5099233aedb45.
Report an issue: GitHub.