Billionmail/BillionMail · error
threads must be less than 100
Error message
threads must be less than 100
What it means
UpdateTaskThreads caps the worker-thread count at 100. Requesting more than 100 threads is rejected to prevent unbounded goroutine creation and resource exhaustion on the sending pool. The check runs before task lookup and pool resize.
Source
Thrown at core/internal/service/batch_mail/task_executor.go:1465
return map[string]interface{}{
"sent_count": sent,
"failed_count": failed,
"total_count": total,
"success_rate": successRate,
"current_speed": e.rateController.GetCurrentRate(),
"max_rate": e.rateController.GetMaxRate(),
"duration_sec": duration,
}
}
func (e *TaskExecutor) UpdateTaskThreads(taskId int, threads int) error {
// parameter validation
if threads <= 0 {
return fmt.Errorf("threads must be greater than zero")
}
if threads > 100 {
return fmt.Errorf("threads must be less than 100")
}
// get task info
task, err := GetTaskInfo(context.Background(), taskId)
if err != nil {
return fmt.Errorf("get task info failed: %w", err)
}
if task == nil || task.Id == 0 {
return fmt.Errorf("task %d not found", taskId)
}
// record current pool status
var oldPoolSize int
var runningWorkers int
if e.pool != nil {
oldPoolSize = e.pool.Cap()
runningWorkers = e.pool.Running()View on GitHub (pinned to fc36c76c05)
Solutions
- Use a threads value of 100 or less.
- Clamp the input in the handler: if threads > 100 { threads = 100 } or return a 400 stating the allowed range 1-100.
- Document the 1-100 range in the API/UI so clients don't attempt higher values.
Example fix
// before await api.updateTaskThreads(taskId, 500) // after const threads = Math.min(Math.max(requested, 1), 100) await api.updateTaskThreads(taskId, threads)
Defensive patterns
Strategy: validation
Validate before calling
// Go
const maxThreads = 100
if threads > maxThreads {
threads = maxThreads // or reject, per product rules
} Type guard
// TypeScript (client)
const threads = Math.min(Math.max(Number(input) || 1, 1), 100)
export function clampThreads(n: number): number { return Math.min(Math.max(n, 1), 100) } Try / catch
if err := executor.UpdateTaskThreads(taskId, threads); err != nil {
if strings.Contains(err.Error(), "less than 100") {
return executor.UpdateTaskThreads(taskId, 100)
}
return err
} Prevention
- Clamp thread inputs to 1-100 in both UI and API layer.
- Publish the limit in API docs and the admin UI slider bounds.
- Log clamping events so requests asking for oversized values are visible.
When it happens
Trigger: Calling UpdateTaskThreads(taskId, n) with n > 100, e.g. a client trying to max out sending speed or an unvalidated query/body parameter.
Common situations: Admin UIs without an upper bound; API consumers guessing at allowed limits; automation scripts scaling threads without knowing the cap.
Related errors
- threads must be greater than zero
- You cannot create more than 5000 batches
- JWT missing group_token claim
- end_time must greater than start_time
- task %d not found
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/5bf5aa1124434dfe.
Report an issue: GitHub.