{"id":"160c76ebcc7db03f","repo":"go-redis/redis","slug":"redis-at-least-one-metric-must-be-specified-for-h","errorCode":null,"errorMessage":"redis: at least one metric must be specified for HOTKEYS START","messagePattern":"redis: at least one metric must be specified for HOTKEYS START","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hotkeys_commands.go","lineNumber":54,"sourceCode":"\t// Metrics to track. At least one must be specified.\n\tMetrics []HotKeysMetric\n\t// Count is the number of top keys to report.\n\t// Default: 10, Min: 10, Max: 64\n\tCount uint8\n\t// Duration is the auto-stop tracking after this many seconds.\n\t// Default: 0 (no auto-stop)\n\tDuration int64\n\t// Sample is the sample ratio - track keys with probability 1/sample.\n\t// Default: 1 (track every key), Min: 1\n\tSample int64\n\t// Slots specifies specific hash slots to track (0-16383).\n\t// All specified slots must be hosted by the receiving node.\n\t// If not specified, all slots are tracked.\n\tSlots []uint16\n}\n\n// ErrHotKeysNoMetrics is returned when HotKeysStart is called without any metrics specified.\nvar ErrHotKeysNoMetrics = errors.New(\"redis: at least one metric must be specified for HOTKEYS START\")\n\n// HotKeysStart starts collecting hotkeys data.\n// At least one metric must be specified in args.Metrics.\n// This command is only available on standalone clients.\nfunc (c *Client) HotKeysStart(ctx context.Context, args *HotKeysStartArgs) *StatusCmd {\n\tcmdArgs := make([]interface{}, 0, 16)\n\tcmdArgs = append(cmdArgs, \"hotkeys\", \"start\")\n\n\t// Validate that at least one metric is specified\n\tif len(args.Metrics) == 0 {\n\t\tcmd := NewStatusCmd(ctx, cmdArgs...)\n\t\tcmd.SetErr(ErrHotKeysNoMetrics)\n\t\treturn cmd\n\t}\n\n\tcmdArgs = append(cmdArgs, \"metrics\", len(args.Metrics))\n\tfor _, metric := range args.Metrics {\n\t\tcmdArgs = append(cmdArgs, strings.ToLower(string(metric)))","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/hotkeys_commands.go#L36-L72","documentation":"ErrHotKeysNoMetrics is returned by (*Client).HotKeysStart when args.Metrics is empty (hotkeys_commands.go:64-67). The HOTKEYS START command requires at least one metric to track; the library validates this client-side and sets the error on the returned *StatusCmd without dispatching. Note HOTKEYS is standalone-only (not on Cluster/Ring/Universal).","triggerScenarios":"Calling client.HotKeysStart(ctx, &HotKeysStartArgs{}) or with Metrics: nil on a *redis.Client.","commonSituations":"Constructing HotKeysStartArgs with only Count/Duration set and forgetting Metrics, or passing a zero-value struct.","solutions":["Populate args.Metrics with at least redis.HotKeysMetricCPU and/or redis.HotKeysMetricNET.","Assert len(args.Metrics) > 0 before calling."],"exampleFix":"// before\nclient.HotKeysStart(ctx, &redis.HotKeysStartArgs{Count: 20})\n// after\nclient.HotKeysStart(ctx, &redis.HotKeysStartArgs{\n    Metrics: []redis.HotKeysMetric{redis.HotKeysMetricCPU, redis.HotKeysMetricNET},\n    Count:   20,\n})","handlingStrategy":"validation","validationCode":"if len(args.Metrics) == 0 {\n    args.Metrics = []redis.HotKeysMetric{redis.HotKeysMetricCPU}\n}\nclient.HotKeysStart(ctx, args)","typeGuard":"func validHotKeysArgs(a *redis.HotKeysStartArgs) bool {\n    return a != nil && len(a.Metrics) > 0\n}","tryCatchPattern":"cmd := client.HotKeysStart(ctx, args)\nif err := cmd.Err(); errors.Is(err, redis.ErrHotKeysNoMetrics) {\n    args.Metrics = []redis.HotKeysMetric{redis.HotKeysMetricCPU}\n    cmd = client.HotKeysStart(ctx, args)\n}","preventionTips":["Always populate args.Metrics — CPU and/or NET.","Remember HOTKEYS is standalone-*Client only; type-assert UniversalClient."],"tags":["hotkeys","validation","standalone-only"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}