hashicorp/nomad · error
Invalid task directory given: %q
Error message
Invalid task directory given: %q
What it means
TaskTemplateManagerConfig.Validate() rejects the config when c.TaskDir is the empty string. The task directory is required because the template runner renders consul-template outputs into the task's sandbox directory. NewTaskTemplateManager calls Validate as its first step, so a manager can never be created without a TaskDir.
Source
Thrown at client/allocrunner/taskrunner/template/template.go:162
// Nomad custom RenderFunc used for sandboxing. This is currently used by
// the secrets block to hold all templated data in memory.
RenderFunc renderer.Renderer
}
// Validate validates the configuration.
func (c *TaskTemplateManagerConfig) Validate() error {
if c == nil {
return fmt.Errorf("Nil config passed")
} else if c.UnblockCh == nil {
return fmt.Errorf("Invalid unblock channel given")
} else if c.Lifecycle == nil {
return fmt.Errorf("Invalid lifecycle hooks given")
} else if c.Events == nil {
return fmt.Errorf("Invalid event hook given")
} else if c.ClientConfig == nil {
return fmt.Errorf("Invalid client config given")
} else if c.TaskDir == "" {
return fmt.Errorf("Invalid task directory given: %q", c.TaskDir)
} else if c.EnvBuilder == nil {
return fmt.Errorf("Invalid task environment given")
} else if c.MaxTemplateEventRate == 0 {
return fmt.Errorf("Invalid max template event rate given")
}
// Once is a runner config, but in Nomad it is set per template, so all
// templates given to a runner should have the same value for Once.
var once bool
for i, t := range c.Templates {
if i == 0 {
once = t.Once
} else if t.Once != once {
return fmt.Errorf("All templates should have same Once value")
}
}
return nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Set config.TaskDir to the task's directory path before calling NewTaskTemplateManager.
- Ensure the alloc dir/task dir is created and its path propagated into the task runner config before template manager construction.
- If writing tests, populate TaskDir with a t.TempDir() value in the config fixture.
Example fix
// before
cfg := &template.TaskTemplateManagerConfig{
UnblockCh: ch,
Lifecycle: lc,
Events: ev,
ClientConfig: cc,
}
// after
cfg := &template.TaskTemplateManagerConfig{
UnblockCh: ch,
Lifecycle: lc,
Events: ev,
ClientConfig: cc,
TaskDir: taskDir, // e.g. filepath.Join(allocDir, taskName)
} Defensive patterns
Strategy: validation
Validate before calling
if cfg == nil || cfg.TaskDir == "" {
return fmt.Errorf("template manager config needs a non-empty TaskDir")
} Type guard
func hasTaskDir(c *template.TaskTemplateManagerConfig) bool { return c != nil && c.TaskDir != "" } Try / catch
tm, err := template.NewTaskTemplateManager(cfg)
if err != nil {
return fmt.Errorf("creating template manager: %w", err)
} Prevention
- Build TaskTemplateManagerConfig through a single constructor that always sets TaskDir from the task directory handle.
- Write a unit-test fixture helper that fills all required config fields.
- Fail fast at startup with a clear message if the task dir path is empty.
When it happens
Trigger: Calling NewTaskTemplateManager with a *TaskTemplateManagerConfig whose TaskDir field was never set (left as ""), typically because the caller building the config did not wire in the allocrunner's task directory handle.
Common situations: Custom client-side tooling or tests constructing TaskTemplateManagerConfig by hand; refactors of alloc runner code where the task dir is assigned after the template manager is built; mis-ordered initialization in a task runner setup.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid task environment given
- Invalid max template event rate given
- All templates should have same Once value
- Failed to parse signal %q
- wait config is nil or empty
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5577618a138cf0a8.
Report an issue: GitHub.