Billionmail/BillionMail · error
threads must be greater than zero
Error message
threads must be greater than zero
What it means
UpdateTaskThreads validates the requested worker-thread count before touching the task. A threads value of zero or negative is rejected with this error, since a worker pool cannot run with no threads. It is the first guard in the function, before task lookup or pool resizing.
Source
Thrown at core/internal/service/batch_mail/task_executor.go:1461
if total > 0 {
successRate = float64(sent) / float64(total)
}
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 intView on GitHub (pinned to fc36c76c05)
Solutions
- Pass a threads value of 1-100.
- Mark the threads field required in the API request schema and reject missing values at the handler.
- Clamp/validate user input in the UI to a minimum of 1 before calling the endpoint.
Example fix
// before: field omitted in request
{"taskId": 42}
// after
{"taskId": 42, "threads": 10} Defensive patterns
Strategy: validation
Validate before calling
// Go
if threads <= 0 {
return fmt.Errorf("threads must be in [1,100], got %d", threads)
} Type guard
// TypeScript (client)
function isValidThreads(n: unknown): n is number {
return typeof n === 'number' && Number.isInteger(n) && n >= 1 && n <= 100
} Try / catch
if err := executor.UpdateTaskThreads(taskId, threads); err != nil {
if strings.Contains(err.Error(), "threads must be") {
return gerror.Newf(gerror.CodeInvalidParameter, "invalid threads %d: %v", threads, err)
}
return err
} Prevention
- Make threads a required field in the request DTO so omission fails binding, not silently as 0.
- Validate 1 <= threads <= 100 at the API boundary and in the UI input.
- Never pass raw user input straight into UpdateTaskThreads.
When it happens
Trigger: Calling UpdateTaskThreads(taskId, 0) or with any negative value, typically from an HTTP handler bound to a request body where threads was omitted (zero value) or supplied as a negative number.
Common situations: API clients posting JSON without the threads field (Go decodes it as 0); UI sliders allowing 0; manual curl tests with negative numbers.
Related errors
- threads must be less than 100
- JWT missing group_token claim
- end_time must greater than start_time
- task %d not found
- required column 'email' not found
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/7103cc1ab8d0bc93.
Report an issue: GitHub.