hibiken/asynq · error
cannot encode nil server info
Error message
cannot encode nil server info
What it means
EncodeServerInfo marshals a *ServerInfo into protobuf bytes for persisting server state in Redis. The library throws this error when the caller passes a nil pointer, because there is no meaningful encoding of a missing server record. It is a defensive guard against a nil argument that would otherwise panic inside proto marshaling.
Solutions
- Check that the *base.ServerInfo passed to EncodeServerInfo/WriteServerState is non-nil before calling; construct it with a proper literal (Host, PID, Concurrency, Queues, Started).
- If the info comes from a constructor, handle its error path instead of propagating a nil pointer.
- In tests, allocate the struct (e.g. info := &base.ServerInfo{...}) rather than declaring a bare var of pointer type.
Example fix
// before
var info *base.ServerInfo
err := WriteServerState(info) // cannot encode nil server info
// after
info := &base.ServerInfo{
Host: "localhost",
PID: os.Getpid(),
Concurrency: 10,
Queues: map[string]int{"default": 1},
Started: time.Now(),
}
err := WriteServerState(info) Defensive patterns
Strategy: validation
Validate before calling
if info == nil {
info = &base.ServerInfo{
Host: host,
PID: os.Getpid(),
Concurrency: concurrency,
Queues: queues,
Started: time.Now(),
}
}
err := base.EncodeServerInfo(info) Type guard
func serverInfoOk(info *base.ServerInfo) bool { return info != nil && info.Queues != nil } Try / catch
b, err := base.EncodeServerInfo(info)
if err != nil {
return fmt.Errorf("encode server info: %w", err)
} Prevention
- Never declare ServerInfo as a bare nil pointer; always construct with a struct literal.
- Check error returns of constructors that produce ServerInfo instead of using the pointer when err != nil.
- Add nil assertions in tests that exercise WriteServerState.
When it happens
Trigger: Calling base.EncodeServerInfo(nil) directly, or WriteServerState reaching a call site where the *base.ServerInfo constructed by the caller is nil (e.g. a constructor that failed silently or a struct pointer never assigned).
Common situations: Building the ServerInfo from config where a setup function returns nil on partial failure; tests constructing server state manually and forgetting to allocate the struct; refactors that change a value-returning constructor to a pointer-returning one that can return nil.
Related errors
- cannot encode nil worker 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/0db17d46c59b4194.
Report an issue: GitHub.
Appendix: source
Thrown at internal/base/base.go:381
}
// ServerInfo holds information about a running server.
type ServerInfo struct {
Host string
PID int
ServerID string
Concurrency int
Queues map[string]int
StrictPriority bool
Status string
Started time.Time
ActiveWorkerCount int
}
// EncodeServerInfo marshals the given ServerInfo and returns the encoded bytes.
func EncodeServerInfo(info *ServerInfo) ([]byte, error) {
if info == nil {
return nil, fmt.Errorf("cannot encode nil server info")
}
queues := make(map[string]int32, len(info.Queues))
for q, p := range info.Queues {
queues[q] = int32(p)
}
started := timestamppb.New(info.Started)
return proto.Marshal(&pb.ServerInfo{
Host: info.Host,
Pid: int32(info.PID),
ServerId: info.ServerID,
Concurrency: int32(info.Concurrency),
Queues: queues,
StrictPriority: info.StrictPriority,
Status: info.Status,
StartTime: started,
ActiveWorkerCount: int32(info.ActiveWorkerCount),
})View on GitHub (pinned to d135f1439b)