{"record":{"id":"f4ae6327bd167b5b","repo":"hibiken/asynq","slug":"batch-enqueue-does-not-support-group-tasks","errorCode":null,"errorMessage":"batch enqueue does not support group tasks","messagePattern":"batch enqueue does not support group tasks","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client.go","lineNumber":529,"sourceCode":"\titemMetas := make([]itemMeta, 0, len(tasks))\n\n\tfor i, task := range tasks {\n\t\tif task == nil {\n\t\t\tresults[i] = BatchEnqueueResult{Err: fmt.Errorf(\"task cannot be nil\")}\n\t\t\tcontinue\n\t\t}\n\t\tif strings.TrimSpace(task.Type()) == \"\" {\n\t\t\tresults[i] = BatchEnqueueResult{Err: fmt.Errorf(\"task typename cannot be empty\")}\n\t\t\tcontinue\n\t\t}\n\t\tmerged := append(task.opts, opts...)\n\t\topt, err := composeOptions(merged...)\n\t\tif err != nil {\n\t\t\tresults[i] = BatchEnqueueResult{Err: err}\n\t\t\tcontinue\n\t\t}\n\t\tif opt.group != \"\" {\n\t\t\tresults[i] = BatchEnqueueResult{Err: fmt.Errorf(\"batch enqueue does not support group tasks\")}\n\t\t\tcontinue\n\t\t}\n\t\tif opt.uniqueTTL > 0 {\n\t\t\tresults[i] = BatchEnqueueResult{Err: fmt.Errorf(\"batch enqueue does not support unique tasks\")}\n\t\t\tcontinue\n\t\t}\n\t\tdeadline := noDeadline\n\t\tif !opt.deadline.IsZero() {\n\t\t\tdeadline = opt.deadline\n\t\t}\n\t\ttimeout := noTimeout\n\t\tif opt.timeout != 0 {\n\t\t\ttimeout = opt.timeout\n\t\t}\n\t\tif deadline.Equal(noDeadline) && timeout == noTimeout {\n\t\t\ttimeout = defaultTimeout\n\t\t}\n\t\tmsg := &base.TaskMessage{","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/hibiken/asynq/blob/d135f1439bee74e989b7f9b41ecd542cc87f024a/client.go#L511-L547","documentation":"BatchEnqueue does not allow tasks enqueued with a group option (asynq.Queue with Group used for aggregation). Because batch enqueue bypasses per-task group routing, asynq rejects any item whose composed options contain a non-empty group. The error is recorded per-item in BatchEnqueueResult.Err.","triggerScenarios":"Calling Client.BatchEnqueue with tasks whose options include asynq.Group(\"some-group\") — e.g. batch-submitting aggregation tasks that were configured for group-based aggregation on a Redis cluster.","commonSituations":"Mixing group/aggregation tasks into a shared batch-enqueue helper; enabling group aggregation via a config flag and passing the option unconditionally; migrating from single Enqueue to BatchEnqueue without auditing per-task options.","solutions":["Remove the asynq.Group(...) option for tasks submitted through BatchEnqueue, or enqueue group tasks individually with Client.Enqueue.","Split the batch: enqueue group tasks one-by-one and only batch-enqueue non-group tasks.","Make the enqueue helper configurable so group tasks bypass the batch path.","Check each BatchEnqueueResult.Err to identify and re-enqueue rejected items individually."],"exampleFix":"// before\nopt := []asynq.Option{asynq.Queue(\"events\"), asynq.Group(\"events:2024-01\")}\nclient.BatchEnqueue(ctx, task) // rejected\n// after\nif opts.group != \"\" {\n    _, err := client.Enqueue(task, opts...)\n} else {\n    client.BatchEnqueue(ctx, task)\n}","handlingStrategy":"validation","validationCode":"func batchable(opts []asynq.Option) bool {\n    o := asynq.ComposeOptions(opts...)\n    return o.GetGroup() == \"\"\n}","typeGuard":"func isGroupFreeTask(opts []asynq.Option) bool { return asynq.ComposeOptions(opts...).GetGroup() == \"\" }","tryCatchPattern":"for i, r := range results {\n    if r.Err != nil && strings.Contains(r.Err.Error(), \"does not support group tasks\") {\n        // fall back to single enqueue\n    }\n}","preventionTips":["Keep group tasks out of shared batch-enqueue helpers.","Document that BatchEnqueue forbids group and unique options.","Audit option sets when introducing batch enqueue.","Handle per-item errors instead of assuming whole-batch success."],"tags":["go","asynq","batch-enqueue","unsupported-operation"],"backgroundTag":"unsupported-operation","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"}