{"record":{"id":"7af1a2b50ad19a7d","repo":"hashicorp/nomad","slug":"invalid-lifecycle-hooks-given","errorCode":null,"errorMessage":"Invalid lifecycle hooks given","messagePattern":"Invalid lifecycle hooks given","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/template/template.go","lineNumber":156,"sourceCode":"\t// in downstream platform-specific template runner consumers\n\tTaskID string\n\n\tLogger hclog.Logger\n\n\t// RenderFunc allows custom rendering of templated data, and overrides the\n\t// Nomad custom RenderFunc used for sandboxing. This is currently used by\n\t// the secrets block to hold all templated data in memory.\n\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","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/template/template.go#L138-L174","documentation":"Sentinel validation guard in TaskTemplateManagerConfig.Validate: the caller constructed the manager config without a Lifecycle (hooks) value, so the template manager would have nothing to invoke on template events. It fires only when NewTaskTemplateManager is handed a struct that skipped setting Lifecycle.","triggerScenarios":"Thrown at client/allocrunner/taskrunner/template/template.go:156 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Set the Lifecycle field on TaskTemplateManagerConfig before calling NewTaskTemplateManager","Ensure the taskrunner constructs its lifecycle hooks and passes them into the config struct"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}