{"record":{"id":"8d92537df9edac6d","repo":"hashicorp/nomad","slug":"action-s-defined-multiple-times","errorCode":null,"errorMessage":"Action %s defined multiple times","messagePattern":"Action (.+?) defined multiple times","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8356,"sourceCode":"\n\t\tif other, ok := destinations[tmpl.DestPath]; ok {\n\t\t\touter := fmt.Errorf(\"Template %d has same destination as %d\", idx+1, other)\n\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t} else {\n\t\t\tdestinations[tmpl.DestPath] = idx + 1\n\t\t}\n\t}\n\n\t// Validate actions.\n\tactions := make(map[string]bool)\n\tfor _, action := range t.Actions {\n\t\tif err := action.Validate(); err != nil {\n\t\t\touter := fmt.Errorf(\"Action %s validation failed: %s\", action.Name, err)\n\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t}\n\n\t\tif handled, seen := actions[action.Name]; seen && !handled {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Action %s defined multiple times\", action.Name))\n\t\t\tactions[action.Name] = true\n\t\t\tcontinue\n\t\t}\n\t\tactions[action.Name] = false\n\t}\n\n\t// Validate the dispatch payload block if there\n\tif t.DispatchPayload != nil {\n\t\tif err := t.DispatchPayload.Validate(); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Dispatch Payload validation failed: %v\", err))\n\t\t}\n\t}\n\n\t// Validate the Lifecycle block if there\n\tif t.Lifecycle != nil {\n\t\tif err := t.Lifecycle.Validate(); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Lifecycle validation failed: %v\", err))\n\t\t}","sourceCodeStart":8338,"sourceCodeEnd":8374,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8338-L8374","documentation":"Task.Validate tracks action names in a map and emits \"Action %s defined multiple times\" when the same action name appears in more than one action block within the same task. Duplicate names would make handler dispatch ambiguous, so it is rejected at validation.","triggerScenarios":"A single task declares two `action` blocks with the identical `name`; generated or templated HCL duplicating action names.","commonSituations":"Copy-pasting an action block to add a second command while forgetting to rename it; programmatic job generation concatenating action lists.","solutions":["Rename one of the duplicate action blocks so names are unique per task","Merge the commands into one action script if they belong together","Run `nomad job validate` to catch duplicates before submission"],"exampleFix":"// before\naction \"cleanup\" {\n  command = \"/bin/a.sh\"\n}\naction \"cleanup\" {\n  command = \"/bin/b.sh\"\n}\n// after\naction \"cleanup-a\" {\n  command = \"/bin/a.sh\"\n}\naction \"cleanup-b\" {\n  command = \"/bin/b.sh\"\n}","handlingStrategy":"validation","validationCode":"names := map[string]bool{}\nfor _, a := range task.Actions {\n    if names[a.Name] { return fmt.Errorf(\"duplicate action %q\", a.Name) }\n    names[a.Name] = true\n}","typeGuard":null,"tryCatchPattern":"if err := job.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"defined multiple times\") { /* rename duplicates */ }\n}","preventionTips":["Enforce unique action names in job-generation code","Code-review copy-pasted action blocks","Add a schema lint for duplicate names per task"],"tags":["nomad","job-validation","action","duplicate"],"backgroundTag":"job-spec-validation-failed","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"}