{"record":{"id":"856af123d6f2474c","repo":"hashicorp/nomad","slug":"invalid-task-environment-given","errorCode":null,"errorMessage":"Invalid task environment given","messagePattern":"Invalid task environment given","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/template/template.go","lineNumber":164,"sourceCode":"\tRenderFunc renderer.Renderer\n}\n\n// Validate validates the configuration.\nfunc (c *TaskTemplateManagerConfig) Validate() error {\n\tif c == nil {\n\t\treturn fmt.Errorf(\"Nil config passed\")\n\t} else if c.UnblockCh == nil {\n\t\treturn fmt.Errorf(\"Invalid unblock channel given\")\n\t} else if c.Lifecycle == nil {\n\t\treturn fmt.Errorf(\"Invalid lifecycle hooks given\")\n\t} else if c.Events == nil {\n\t\treturn fmt.Errorf(\"Invalid event hook given\")\n\t} else if c.ClientConfig == nil {\n\t\treturn fmt.Errorf(\"Invalid client config given\")\n\t} else if c.TaskDir == \"\" {\n\t\treturn fmt.Errorf(\"Invalid task directory given: %q\", c.TaskDir)\n\t} else if c.EnvBuilder == nil {\n\t\treturn fmt.Errorf(\"Invalid task environment given\")\n\t} else if c.MaxTemplateEventRate == 0 {\n\t\treturn fmt.Errorf(\"Invalid max template event rate given\")\n\t}\n\n\t// Once is a runner config, but in Nomad it is set per template, so all\n\t// templates given to a runner should have the same value for Once.\n\tvar once bool\n\tfor i, t := range c.Templates {\n\t\tif i == 0 {\n\t\t\tonce = t.Once\n\t\t} else if t.Once != once {\n\t\t\treturn fmt.Errorf(\"All templates should have same Once value\")\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/template/template.go#L146-L182","documentation":"Validate() requires a non-nil EnvBuilder (*taskenv.Builder) on TaskTemplateManagerConfig. The environment builder is used to expand environment variables in template output paths and to inject rendered values into the task environment. A nil builder makes template rendering unsafe, so the manager refuses to start.","triggerScenarios":"Calling NewTaskTemplateManager with a config where EnvBuilder was omitted/nil — the caller did not pass the taskenv.Builder built from the task's environment in the task runner setup.","commonSituations":"Hand-rolled config construction in tests or plugins; refactors where the env builder is created later in the startup sequence than the template manager; forgetting to thread the builder through a wrapper.","solutions":["Construct and assign the *taskenv.Builder for the task before calling NewTaskTemplateManager.","Ensure the task runner builds the env builder (taskenv.NewBuilder with node/alloc config) prior to template manager creation.","In tests, initialize EnvBuilder with taskenv.NewBuilder(...) in the fixture config."],"exampleFix":"// before\ncfg := &template.TaskTemplateManagerConfig{\n    TaskDir: taskDir,\n    ClientConfig: cc,\n}\n// after\nenvBuilder := taskenv.NewBuilder(node, alloc, task, region).\n    SetHookResources(...)\ncfg := &template.TaskTemplateManagerConfig{\n    TaskDir: taskDir,\n    EnvBuilder: envBuilder,\n    ClientConfig: cc,\n}","handlingStrategy":"validation","validationCode":"if cfg == nil || cfg.EnvBuilder == nil {\n    return fmt.Errorf(\"template manager config needs a non-nil EnvBuilder\")\n}","typeGuard":"func hasEnvBuilder(c *template.TaskTemplateManagerConfig) bool { return c != nil && c.EnvBuilder != nil }","tryCatchPattern":"tm, err := template.NewTaskTemplateManager(cfg)\nif err != nil {\n    return fmt.Errorf(\"creating template manager: %w\", err)\n}","preventionTips":["Create the taskenv.Builder early in task runner setup and pass it explicitly.","Add a lint/test asserting all required config fields are non-nil before NewTaskTemplateManager.","Keep the env builder's lifetime tied to the task runner so it is never dropped during refactors."],"tags":["config","validation","nomad-client","template"],"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"}