hashicorp/nomad · error
error parsing: root should be an object
Error message
error parsing: root should be an object
What it means
Returned by parseNamespaceSpec when an HCL namespace spec file (used by `nomad namespace apply` style flows) parses to something other than an *ast.ObjectList at the root. The parser expects the file's top level to be an object of blocks (e.g. `namespace { ... }`); a bare scalar, string, or array at the top level fails this type assertion.
Source
Thrown at command/namespace_apply.go:208
return 1
}
c.Ui.Output(fmt.Sprintf("Successfully applied namespace %q!", namespace.Name))
return 0
}
// parseNamespaceSpec is used to parse the namespace specification from HCL
func parseNamespaceSpec(input []byte) (*api.Namespace, 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 spec api.Namespace
if err := parseNamespaceSpecImpl(&spec, list); err != nil {
return nil, err
}
return &spec, nil
}
// parseNamespaceSpec parses the quota namespace taking as input the AST tree
func parseNamespaceSpecImpl(result *api.Namespace, 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
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the file's top level is an object: wrap contents in `namespace { ... }`.
- Compare against a known-good spec from `nomad namespace inspect <name>`.
- Validate HCL syntax with `hclfmt` or an HCL linter before applying.
- Do not feed JSON-formatted specs where HCL object blocks are expected.
- Check the file is non-empty and was fully saved/copied.
Example fix
// before: fields floating at top level
name = "prod"
description = "production"
// after
namespace "prod" {
description = "production"
} Defensive patterns
Strategy: validation
Validate before calling
// ensure the spec root is an object block before applying
grep -q '^namespace' "$SPEC_FILE" || { echo "$SPEC_FILE must contain a top-level namespace block"; exit 1; } Type guard
func isObjectList(root *ast.Node) bool {
_, ok := root.(*ast.ObjectList)
return ok
} Try / catch
spec, err := parseNamespaceSpec(path)
if err != nil && strings.Contains(err.Error(), "root should be an object") {
return fmt.Errorf("%s: wrap contents in a top-level `namespace { ... }` block", path)
} Prevention
- Always keep the `namespace "name" { ... }` block wrapper in spec files.
- Generate specs from `nomad namespace inspect` instead of hand-writing.
- Lint HCL files with hclfmt before applying.
- Never reuse JSON output files as HCL spec inputs.
When it happens
Trigger: Feeding `nomad namespace apply` a spec file whose content is not an object — e.g. a JSON array, a quoted string, an empty file that parses oddly, or HCL where the namespace block wrapper was omitted and only fields were pasted at top level in an unexpected shape.
Common situations: Hand-editing an exported namespace spec and accidentally deleting the `namespace { ... }` block wrapper; saving JSON output back as an HCL input; copying a partial snippet instead of the full block; CRLF/encoding oddities leaving only stray tokens.
Related errors
- failed to parse config:
- Label encoding failed: %v
- <combined HCL diagnostics from str.String()>
- Failed to parse ACL Policy: %v
- failed to parse HCL file %s: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0eeebdb9e8181601.
Report an issue: GitHub.