hashicorp/nomad · error
error parsing: root should be an object
Error message
error parsing: root should be an object
What it means
parseVariableSpec parses HCL input for `var put` and expects the top-level node to be an ObjectList (an HCL object). If the parsed root is anything else (e.g. the file is JSON, or contains only scalar/list values), the parser returns the fixed message `error parsing: root should be an object`.
Source
Thrown at command/var_put.go:480
out.CreateTime = 0
out.ModifyIndex = 0
out.ModifyTime = 0
}
return out, nil
}
// parseVariableSpec is used to parse the variable specification
// from HCL
func parseVariableSpec(input []byte, verbose func(string)) (*api.Variable, error) {
root, err := hcl.ParseBytes(input)
if err != nil {
return nil, err
}
// Top-level item should be a list
list, ok := root.Node.(*ast.ObjectList)
if !ok {
return nil, fmt.Errorf("error parsing: root should be an object")
}
var out api.Variable
if err := parseVariableSpecImpl(&out, list); err != nil {
return nil, err
}
return &out, nil
}
// parseVariableSpecImpl parses the variable taking as input the AST tree
func parseVariableSpecImpl(result *api.Variable, list *ast.ObjectList) error {
// Decode the full thing into a map[string]interface for ease
var m map[string]any
if err := hcl.DecodeObject(&m, list); err != nil {
return err
}
// Check for invalid keysView on GitHub (pinned to 482b49bf1a)
Solutions
- Check the file actually contains HCL object syntax at top level (key = value or block {}), not JSON or a bare list.
- If the content is JSON, rerun with `-in=json`.
- Regenerate a valid template with `nomad var init` and port your values into it.
- Ensure the file is not empty or comment-only.
Example fix
// before (JSON passed as HCL)
{ "path": "app/config" }
// after (HCL form)
path = "app/config"
items { key = "value" } Defensive patterns
Strategy: validation
Validate before calling
// pre-parse and confirm the HCL root is an object before invoking the command
f, _ := hcl.ParseBytes(data)
if _, ok := f.Node.(*hclast.ObjectList); !ok {
return errors.New("HCL spec root must be an object (key = value / blocks)")
} Type guard
func isHCLObjectRoot(data []byte) bool {
root, err := hcl.ParseBytes(data)
if err != nil { return false }
_, ok := root.Node.(*hclast.ObjectList)
return ok
} Try / catch
if err := run(); err != nil && strings.Contains(err.Error(), "root should be an object") {
log.Fatal("you likely passed JSON content with -in=hcl; switch flags or convert the file")
} Prevention
- Match file extension and content format, and set -in explicitly.
- Use HCL block/key=value syntax at top level, never JSON braces.
- Regenerate specs from `nomad var init` rather than converting formats by hand.
When it happens
Trigger: Feeding `nomad var put -in=hcl` a file whose top level is not an HCL object — for example a bare JSON document (JSON object lists do not come through as *ast.ObjectList in this parser), a file containing only a list or a bare string, or an empty file.
Common situations: Mixing up -in flags: passing JSON content with -in=hcl; a spec file that starts with comments only; writing an HCL file with top-level array syntax `[...]` instead of blocks/assignments.
Related errors
- Unable to parse job submission to re-enable scaling policies
- error parsing hcl: %w
- failed to convert task schema
- <combined HCL diagnostics from str.String()>
- error parsing: root should be an object
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ac7e560530c36bd2.
Report an issue: GitHub.