hibiken/asynq · error
cannot encode nil worker info
Error message
cannot encode nil worker info
What it means
EncodeWorkerInfo marshals a *WorkerInfo (a currently-processing task's worker record) into protobuf bytes to be stored as part of server state. The library throws this when the worker info pointer is nil, since encoding an absent worker is meaningless. It prevents a nil dereference inside proto.Marshal.
Solutions
- Verify each *WorkerInfo is non-nil before adding it to ServerState.Workers or passing it to EncodeWorkerInfo.
- Fix the producer that should construct WorkerInfo (Host, PID, ID, Queue, TaskMessage fields) so it never yields nil.
- Filter nil entries when building the Workers slice.
Example fix
// before
workers := make([]*base.WorkerInfo, len(active))
for i, t := range active {
workers[i] = workerMap[t.ID] // may be nil
}
// after
var workers []*base.WorkerInfo
for _, t := range active {
if w := workerMap[t.ID]; w != nil {
workers = append(workers, w)
}
} Defensive patterns
Strategy: type-guard
Validate before calling
for _, w := range workers {
if w == nil {
return errors.New("nil worker info in server state")
}
} Type guard
func validWorker(w *base.WorkerInfo) bool { return w != nil && w.ID != "" } Try / catch
b, err := base.EncodeWorkerInfo(w)
if err != nil {
log.Printf("skip worker %s: %v", wID, err)
continue
} Prevention
- Filter nil entries out of ServerState.Workers before writing.
- Handle map-lookup misses (w, ok := m[id]) instead of storing nil pointers.
- Keep WorkerInfo construction in one factory function that always returns non-nil or an error.
When it happens
Trigger: Calling base.EncodeWorkerInfo(nil) directly, or WriteServerState being handed a ServerState whose Workers slice contains a nil *WorkerInfo, or a WorkerInfo variable that was never allocated.
Common situations: Application code tracking in-flight tasks that appends pointers from a map lookup which returned nil; test code declaring `var w *base.WorkerInfo` without initialization; a task-processing hook that failed to build the WorkerInfo before heartbeating.
Related errors
- cannot encode nil server info
- cannot encode nil scheduler entry
- cannot encode nil enqueue event
- task id conflicts with another task
- testutil: redis is down
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/ece32a788caa00b6.
Report an issue: GitHub.
Appendix: source
Thrown at internal/base/base.go:443
}
// WorkerInfo holds information about a running worker.
type WorkerInfo struct {
Host string
PID int
ServerID string
ID string
Type string
Payload []byte
Queue string
Started time.Time
Deadline time.Time
}
// EncodeWorkerInfo marshals the given WorkerInfo and returns the encoded bytes.
func EncodeWorkerInfo(info *WorkerInfo) ([]byte, error) {
if info == nil {
return nil, fmt.Errorf("cannot encode nil worker info")
}
startTime := timestamppb.New(info.Started)
deadline := timestamppb.New(info.Deadline)
return proto.Marshal(&pb.WorkerInfo{
Host: info.Host,
Pid: int32(info.PID),
ServerId: info.ServerID,
TaskId: info.ID,
TaskType: info.Type,
TaskPayload: info.Payload,
Queue: info.Queue,
StartTime: startTime,
Deadline: deadline,
})
}
// DecodeWorkerInfo decodes the given bytes into WorkerInfo.View on GitHub (pinned to d135f1439b)