{"record":{"id":"0db17d46c59b4194","repo":"hibiken/asynq","slug":"cannot-encode-nil-server-info","errorCode":null,"errorMessage":"cannot encode nil server info","messagePattern":"cannot encode nil server info","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/base/base.go","lineNumber":381,"sourceCode":"}\n\n// ServerInfo holds information about a running server.\ntype ServerInfo struct {\n\tHost              string\n\tPID               int\n\tServerID          string\n\tConcurrency       int\n\tQueues            map[string]int\n\tStrictPriority    bool\n\tStatus            string\n\tStarted           time.Time\n\tActiveWorkerCount int\n}\n\n// EncodeServerInfo marshals the given ServerInfo and returns the encoded bytes.\nfunc EncodeServerInfo(info *ServerInfo) ([]byte, error) {\n\tif info == nil {\n\t\treturn nil, fmt.Errorf(\"cannot encode nil server info\")\n\t}\n\tqueues := make(map[string]int32, len(info.Queues))\n\tfor q, p := range info.Queues {\n\t\tqueues[q] = int32(p)\n\t}\n\tstarted := timestamppb.New(info.Started)\n\n\treturn proto.Marshal(&pb.ServerInfo{\n\t\tHost:              info.Host,\n\t\tPid:               int32(info.PID),\n\t\tServerId:          info.ServerID,\n\t\tConcurrency:       int32(info.Concurrency),\n\t\tQueues:            queues,\n\t\tStrictPriority:    info.StrictPriority,\n\t\tStatus:            info.Status,\n\t\tStartTime:         started,\n\t\tActiveWorkerCount: int32(info.ActiveWorkerCount),\n\t})","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/hibiken/asynq/blob/d135f1439bee74e989b7f9b41ecd542cc87f024a/internal/base/base.go#L363-L399","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nvar info *base.ServerInfo\nerr := WriteServerState(info) // cannot encode nil server info\n// after\ninfo := &base.ServerInfo{\n    Host: \"localhost\",\n    PID:  os.Getpid(),\n    Concurrency: 10,\n    Queues: map[string]int{\"default\": 1},\n    Started: time.Now(),\n}\nerr := WriteServerState(info)","handlingStrategy":"validation","validationCode":"if info == nil {\n    info = &base.ServerInfo{\n        Host: host,\n        PID: os.Getpid(),\n        Concurrency: concurrency,\n        Queues: queues,\n        Started: time.Now(),\n    }\n}\nerr := base.EncodeServerInfo(info)","typeGuard":"func serverInfoOk(info *base.ServerInfo) bool { return info != nil && info.Queues != nil }","tryCatchPattern":"b, err := base.EncodeServerInfo(info)\nif err != nil {\n    return fmt.Errorf(\"encode server info: %w\", err)\n}","preventionTips":["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."],"tags":["go","nil-pointer","serialization","protobuf"],"backgroundTag":"null-argument","analyzedSha":"d135f1439bee74e989b7f9b41ecd542cc87f024a","analyzedAt":"2026-09-07T19:02:34.660Z","contentChangedAt":"2026-09-07T19:02:34.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}