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

  1. Use a threads value of 100 or less.
  2. Clamp the input in the handler: if threads > 100 { threads = 100 } or return a 400 stating the allowed range 1-100.
  3. 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

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


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