{"record":{"id":"a5e3974024dbb3bb","repo":"hashicorp/nomad","slug":"invalid-change-mode-must-be-one-of-the-following","errorCode":null,"errorMessage":"Invalid change mode. Must be one of the following: noop, signal, script, restart","messagePattern":"Invalid change mode\\. Must be one of the following: noop, signal, script, restart","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8816,"sourceCode":"\tTemplateChangeModeNoop = \"noop\"\n\n\t// TemplateChangeModeSignal marks that the task should be signaled if the\n\t// template is re-rendered\n\tTemplateChangeModeSignal = \"signal\"\n\n\t// TemplateChangeModeRestart marks that the task should be restarted if the\n\t// template is re-rendered\n\tTemplateChangeModeRestart = \"restart\"\n\n\t// TemplateChangeModeScript marks that the task should trigger a script if\n\t// the template is re-rendered\n\tTemplateChangeModeScript = \"script\"\n)\n\nvar (\n\t// TemplateChangeModeInvalidError is the error for when an invalid change\n\t// mode is given\n\tTemplateChangeModeInvalidError = errors.New(\"Invalid change mode. Must be one of the following: noop, signal, script, restart\")\n)\n\n// Template represents a template configuration to be rendered for a given task\ntype Template struct {\n\t// SourcePath is the path to the template to be rendered\n\tSourcePath string\n\n\t// DestPath is the path to where the template should be rendered\n\tDestPath string\n\n\t// EmbeddedTmpl store the raw template. This is useful for smaller templates\n\t// where they are embedded in the job file rather than sent as an artifact\n\tEmbeddedTmpl string\n\n\t// ChangeMode indicates what should be done if the template is re-rendered\n\tChangeMode string\n\n\t// ChangeSignal is the signal that should be sent if the change mode","sourceCodeStart":8798,"sourceCodeEnd":8834,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8798-L8834","documentation":"TemplateChangeModeInvalidError is a package-level sentinel in nomad/structs thrown by Template.Validate() when the template's change_mode field is not one of noop, signal, script, or restart (the default switch branch of validation). Because it's a declared exported variable, tests and callers can compare against it directly.","triggerScenarios":"Submitting a job whose template stanza sets change_mode to an unsupported string (typo like \"signals\", \"reload\", \"re-sart\", or a value from another tool), causing the default case in Template.Validate to append this error.","commonSituations":"Typo or copy-paste from Consul Template config that uses different keys; switching between Nomad versions with different accepted modes and carrying an old value; JSON job specs where change_mode was set programmatically without an enum check.","solutions":["Set change_mode to exactly one of: noop, signal, script, restart.","If you want SIGHUP-style reload behavior use change_mode = \"signal\" together with change_signal.","Remove the change_mode stanza entirely to accept the default (Nomad defaults to \"signal\" where applicable).","Validate the job with `nomad job validate` to catch the typo before submission."],"exampleFix":"// before\ntemplate {\n  data        = \"...\"\n  destination = \"local/app.conf\"\n  change_mode = \"reload\"\n}\n// after\ntemplate {\n  data          = \"...\"\n  destination   = \"local/app.conf\"\n  change_mode   = \"signal\"\n  change_signal = \"SIGHUP\"\n}","handlingStrategy":"validation","validationCode":"var validChangeModes = map[string]bool{\"noop\": true, \"signal\": true, \"script\": true, \"restart\": true}\nfunc validateChangeMode(m string) error {\n\tif !validChangeModes[m] {\n\t\treturn fmt.Errorf(\"invalid change_mode %q: must be noop, signal, script, or restart\", m)\n\t}\n\treturn nil\n}","typeGuard":"func isChangeMode(s string) bool {\n\tswitch s {\n\tcase \"noop\", \"signal\", \"script\", \"restart\":\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"if err := job.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"Invalid change mode\") {\n\t\t// reject the template stanza with a clear message listing allowed modes\n\t}\n\treturn err\n}","preventionTips":["Treat change_mode as an enum in tooling; use a whitelist, never free text.","Check the Nomad version docs for accepted change modes before using newer values.","Run `nomad job validate` before every submission."],"tags":["nomad","template","validation","enum"],"backgroundTag":"invalid-enum-value","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"}