{"record":{"id":"5d9a24bbf74ee1d4","repo":"hashicorp/nomad","slug":"missing-task-names","errorCode":null,"errorMessage":"missing task names","messagePattern":"missing task names","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/client.go","lineNumber":3064,"sourceCode":"\t\tNodeSecret: c.secretNodeID(),\n\t\tRegion:     c.Region(),\n\t\tRPCFn:      c.RPC,\n\t\tCheckWatcher: serviceregistration.NewCheckWatcher(\n\t\t\tc.logger, nsd.NewStatusGetter(c.checkStore),\n\t\t),\n\t}\n\tc.nomadService = nsd.NewServiceRegistrationHandler(c.logger, &cfg)\n}\n\n// verifiedTasks asserts each task in taskNames actually exists in the given alloc,\n// otherwise an error is returned.\nfunc verifiedTasks(logger hclog.Logger, alloc *structs.Allocation, taskNames []string) ([]string, error) {\n\tif alloc == nil {\n\t\treturn nil, fmt.Errorf(\"nil allocation\")\n\t}\n\n\tif len(taskNames) == 0 {\n\t\treturn nil, fmt.Errorf(\"missing task names\")\n\t}\n\n\tgroup := alloc.Job.LookupTaskGroup(alloc.TaskGroup)\n\tif group == nil {\n\t\treturn nil, fmt.Errorf(\"group name in allocation is not present in job\")\n\t}\n\n\tverifiedTasks := make([]string, 0, len(taskNames))\n\n\t// confirm the requested task names actually exist in the allocation\n\tfor _, taskName := range taskNames {\n\t\tif !taskIsPresent(taskName, group.Tasks) {\n\t\t\tlogger.Error(\"task not found in the allocation\", \"task_name\", taskName)\n\t\t\treturn nil, fmt.Errorf(\"task %q not found in allocation\", taskName)\n\t\t}\n\t\tverifiedTasks = append(verifiedTasks, taskName)\n\t}\n","sourceCodeStart":3046,"sourceCodeEnd":3082,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/client.go#L3046-L3082","documentation":"`verifiedTasks` requires at least one task name to verify. When the caller passes an empty taskNames slice, the helper short-circuits with \"missing task names\" because verifying zero tasks is a programming error rather than a meaningful request. This guards the task-level API surface (logs, exec, signals) from no-op calls.","triggerScenarios":"Calling a client task operation (e.g. allocation logs or exec against specific tasks) with an empty list of task names derived from user input, CLI flags, or an API request body that omitted the tasks parameter.","commonSituations":"HTTP API calls where the `task` query parameter was omitted; automation scripts that compute the task list from an empty environment section; tooling that passes nil slices after a failed lookup.","solutions":["Pass at least one valid task name in the request","Default to the allocation's first (or declared) task when the caller provides none","Validate task names in your client code before calling the Nomad client API"],"exampleFix":"// before\nnames := getRequestedTasks(req) // may be empty\nverified, err := verifiedTasks(logger, alloc, names)\n// after\nnames := getRequestedTasks(req)\nif len(names) == 0 {\n    names = []string{defaultTaskName}\n}\nverified, err := verifiedTasks(logger, alloc, names)","handlingStrategy":"validation","validationCode":"if len(taskNames) == 0 {\n    return fmt.Errorf(\"at least one task name is required\")\n}\nverified, err := verifiedTasks(logger, alloc, taskNames)","typeGuard":"func hasTaskNames(names []string) bool {\n    return len(names) > 0\n}","tryCatchPattern":"if err := runTaskOp(alloc, tasks); err != nil {\n    if strings.Contains(err.Error(), \"missing task names\") {\n        // fall back to default task\n    }\n}","preventionTips":["Default to the allocation's primary task when the caller supplies none","Validate request bodies/CLI flags for the task parameter","Never pass nil slices where a task list is expected"],"tags":["nomad","client","validation","tasks"],"backgroundTag":"missing-required-argument","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}