hashicorp/nomad · error
missing node variable
Error message
missing node variable
What it means
TaskEnv.AllValues builds the HCL2 variable tree (env, node, attr, meta) used for interpolation. It requires a 'node' object in the assembled map; since node values normally come from t.NodeAttrs (e.g. 'node.name', 'node.datacenter'), their absence means the TaskEnv was never populated with node data, which the function treats as a fatal programming/setup error.
Source
Thrown at client/taskenv/env.go:323
}
}
// Prepare task-based secrets for use in interpolation
for k, v := range t.TaskSecrets {
if err := addNestedKey(allMap, k, v); err != nil {
errs[k] = err
}
}
// Add flat envMap as a Map to allMap so users can access any key via
// HCL2's indexing syntax: ${env["foo...bar"]}
allMap["env"] = cty.MapVal(envMap)
// Add meta and attr to node if they exist to properly namespace things
// a bit.
nodeMapI, ok := allMap["node"]
if !ok {
return nil, nil, fmt.Errorf("missing node variable")
}
nodeMap, ok := nodeMapI.(map[string]any)
if !ok {
return nil, nil, fmt.Errorf("invalid type for node variable: %T", nodeMapI)
}
if attrMap, ok := allMap["attr"]; ok {
nodeMap["attr"] = attrMap
}
if metaMap, ok := allMap["meta"]; ok {
nodeMap["meta"] = metaMap
}
// ctyify the entire tree of strings and maps
tree, err := ctyify(allMap)
if err != nil {
// This should not be possible and is likely a programming
// error. Invalid user input should be cleaned earlier.
return nil, nil, errView on GitHub (pinned to 482b49bf1a)
Solutions
- Build the TaskEnv via the standard client path (alloc runner's envBuilder with Node attributes) before calling AllValues
- In tests/utilities, populate NodeAttrs with at least node.name/node.datacenter equivalents so a 'node' object exists
- Guard the call: only invoke AllValues on TaskEnv instances that have non-empty NodeAttrs
- If hit in a Nomad hook, capture the alloc/hook context and file an upstream bug — docs call this 'likely a programming error'
Example fix
// before: AllValues on a bare TaskEnv panics into error
tenv := &taskenv.TaskEnv{}
vars, _, err := tenv.AllValues()
// after: build with node attrs first
tenv := taskenv.NewEmptyBuilder().UpdateNode(node).Build()
vars, _, err := tenv.AllValues() Defensive patterns
Strategy: validation
Validate before calling
// Go: verify the TaskEnv has node attributes before calling AllValues
func hasNodeAttrs(t *taskenv.TaskEnv) bool {
if t == nil {
return false
}
for k := range t.NodeAttrs {
if strings.HasPrefix(k, "node.") {
return true
}
}
return false
} Type guard
// Go
func builtTaskEnv(t *taskenv.TaskEnv) (*taskenv.TaskEnv, bool) {
if t == nil || len(t.NodeAttrs) == 0 {
return nil, false
}
return t, true
} Try / catch
// Go
vars, errs, err := tenv.AllValues()
if err != nil {
if strings.Contains(err.Error(), "missing node variable") {
return nil, fmt.Errorf("TaskEnv not built with node attributes; use the client env builder: %w", err)
}
return nil, err
} Prevention
- Always construct TaskEnv via the client's env builder, not struct literals
- In tests, seed NodeAttrs with node.* keys before calling AllValues
- Treat a fatal error from AllValues as a caller bug, not user input
- Check hook ordering so interpolation runs after node attributes are attached
When it happens
Trigger: AllValues() is called on a TaskEnv whose NodeAttrs map contains no keys that nest under 'node' (no node.* attributes were added via Build(), or the empty/partial TaskEnv was constructed without node information).
Common situations: Calling AllValues on a zero-value or manually constructed TaskEnv instead of one built by the client; tests instantiating TaskEnv with only EnvMap; hooks running before node attributes are attached (e.g. pre-restore paths).
Related errors
- invalid type for node variable: %T
- key %q has invalid type %T
- error interpreting desired Envoy version from Consul: %w
- failed to convert parsed config to map: %v
- attribute %q is missing an opening brace
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c4d8bac0a2ce7b97.
Report an issue: GitHub.