hashicorp/nomad · error
root should be an object
Error message
root should be an object
What it means
After parsing the config, hclConfigToAny expects the top-level HCL node to be an ast.ObjectList (a block-style document). If the parsed root is something else (e.g. a bare expression/object), the structure is invalid and this error is returned.
Source
Thrown at plugins/shared/cmd/launcher/command/device.go:233
return nil
}
func hclConfigToAny(config []byte) (any, error) {
if len(config) == 0 {
return map[string]any{}, nil
}
// Parse as we do in the jobspec parser
root, err := hcl.Parse(string(config))
if err != nil {
return nil, fmt.Errorf("failed to hcl parse the config: %v", err)
}
// Top-level item should be a list
list, ok := root.Node.(*ast.ObjectList)
if !ok {
return nil, fmt.Errorf("root should be an object")
}
var m map[string]any
if err := hcl.DecodeObject(&m, list.Items[0]); err != nil {
return nil, fmt.Errorf("failed to decode object: %v", err)
}
return m["config"], nil
}
func (c *Device) startRepl() error {
// Start the output goroutine
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
fingerprint := make(chan context.Context)
stats := make(chan context.Context)
reserve := make(chan []string)
go c.replOutput(ctx, fingerprint, stats, reserve)View on GitHub (pinned to 482b49bf1a)
Solutions
- Wrap the configuration in a proper top-level block, e.g. `config "mock" { ... }`.
- Convert JSON config to HCL block syntax used by the device plugin.
- Verify the launcher is reading the intended config file/section.
Example fix
// before
{ "foo": "bar" }
// after
config "mock" {
foo = "bar"
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure the config contains a top-level block before parsing
if !strings.Contains(string(config), "config ") {
return errors.New("device config must define a top-level `config` block")
} Try / catch
if err := setConfigErr; err != nil && err.Error() == "root should be an object" {
// reject the config file and instruct the operator to use block syntax
} Prevention
- Always wrap device settings in a `config "name" { ... }` block.
- Reject JSON-looking config files at load time.
- Keep an example config next to each device plugin.
- Document the expected top-level structure in plugin docs.
When it happens
Trigger: Passing config whose top level is not a block, e.g. a bare value like {"a":1}-style JSON or a scalar expression instead of `config "name" { ... }` blocks.
Common situations: Supplying JSON config where HCL blocks are expected (JSON objects parse to non-ObjectList nodes); config file containing only a key/value with no enclosing block; concatenating the wrong file.
Related errors
- failed to hcl parse the config: %v
- failed to decode object: %v
- only one storage block is allowed
- failed to parse config:
- Error loading %s: %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d06258be46a0a0ee.
Report an issue: GitHub.