Billionmail/BillionMail · error
get task info failed: %w
Error message
get task info failed: %w
What it means
After validating the thread count, UpdateTaskThreads loads the task via GetTaskInfo; if that lookup fails, the underlying error is wrapped with fmt.Errorf %w and returned as "get task info failed: <cause>". It indicates the task could not be fetched from the database/cache, and the root cause is preserved for errors.Is/As inspection.
Source
Thrown at core/internal/service/batch_mail/task_executor.go:1471
"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()
}
// new threads
newThreads := threads
// calculate new rate limit - 20 emails per thread per second
targetSendPerThreadPerSecond := 20View on GitHub (pinned to fc36c76c05)
Solutions
- Read the wrapped cause (%w) via errors.Is/As or the error string to identify the root failure.
- Check database connectivity and credentials (psql/health check, docker logs for the postgres container).
- Retry the operation once the DB is reachable; add retry with backoff for transient connection errors.
- Verify GetTaskInfo's query/table state if the cause is a SQL error.
Example fix
// before: opaque handling
if err := e.UpdateTaskThreads(id, n); err != nil { log.Print(err) }
// after
if err := e.UpdateTaskThreads(id, n); err != nil {
var dbErr *pgconn.ConnectError
if errors.As(err, &dbErr) { /* alert on DB connectivity */ }
log.Printf("update threads: %v", err)
} Defensive patterns
Strategy: retry
Validate before calling
// Go: verify DB reachability before the operation
if err := g.DB().PingMaster(); err != nil {
return fmt.Errorf("db unavailable: %w", err)
} Type guard
func isDBConnectErr(err error) bool {
var netErr net.Error
return errors.As(err, &netErr) || strings.Contains(err.Error(), "connect: ")
} Try / catch
err := executor.UpdateTaskThreads(taskId, threads)
for i := 0; i < 3 && isDBConnectErr(err); i++ {
time.Sleep(time.Second << i)
err = executor.UpdateTaskThreads(taskId, threads)
}
if err != nil { log.Printf("get task info failed: %v", err) } Prevention
- Monitor PostgreSQL health and connection-pool saturation.
- Use errors.Is/As on the wrapped cause instead of string matching alone.
- Set sane DB timeouts so failures surface fast and retryable.
- Verify credentials/config after every deploy that touches DB settings.
When it happens
Trigger: Calling UpdateTaskThreads while the database is unreachable, the task table query errors (connection refused, timeout, locked table), or GetTaskInfo's context is cancelled.
Common situations: PostgreSQL down or restarting during the call; network partition between app and DB; connection pool exhausted under load; misconfigured DB credentials after a deploy.
Related errors
- task %d: update database threads failed: %w
- failed to get all domains: %w
- fail to check domain: %w
- failed to get all emails: %w
- failed to get all mailboxes: %w
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/0ac5f49e3f517b98.
Report an issue: GitHub.