hashicorp/nomad · error
failed to decode object: %v
Error message
failed to decode object: %v
What it means
Once the root is confirmed an ObjectList, the first item is decoded into a map via hcl.DecodeObject. Failure here (types not decodable, unsupported constructs) is wrapped as this error, before the function returns m["config"].
Source
Thrown at plugins/shared/cmd/launcher/command/device.go:238
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)
c.Ui.Output("> Availabile commands are: exit(), fingerprint(), stop_fingerprint(), stats(), stop_stats(), reserve(id1, id2, ...)")
var fingerprintCtx, statsCtx context.Context
var fingerprintCancel, statsCancel context.CancelFunc
View on GitHub (pinned to 482b49bf1a)
Solutions
- Simplify the top-level config block so its body decodes into a plain map (key = value assignments).
- Move complex/nested structures under the `config` key with supported syntax.
- Check the wrapped %v error for the offending key/line and fix its type.
- Test the config through the device plugin's schema (hclspec) path if supported, which validates types earlier.
Example fix
// before
config "mock" {
options = [ { a = 1 } ]
}
// after
config "mock" {
options = ["a=1"]
} Defensive patterns
Strategy: validation
Validate before calling
// Prefer validating config against the device schema (hclspec) before legacy decode
schema, err := c.getSpec()
if err != nil {
return err
}
if _, diag := hclspecutils.Convert(schema); diag.HasErrors() {
return fmt.Errorf("device schema invalid: %v", diag)
} Try / catch
if err := setConfigErr; err != nil && strings.Contains(err.Error(), "failed to decode object") {
// log the wrapped decoder error and fall back to schema-based parsing if available
} Prevention
- Keep top-level config blocks to simple key = value assignments.
- Avoid legacy-decoder-incompatible constructs (nested object lists) at the top level.
- Validate configs against the device's hclspec schema during CI.
- Pin configs to syntax supported by the legacy hcl package used by the launcher.
When it happens
Trigger: hcl.DecodeObject fails on the top-level block item, e.g. keys with incompatible value types, nested structures the legacy decoder cannot handle, or block items where assignments are expected.
Common situations: Config values with types the legacy hcl decoder mishandles (lists of objects, heredocs in odd positions); mixing blocks where a single object is expected; porting config from newer hcl2 syntax not supported by the legacy decoder.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode HCL file %s: %w
- failed to hcl parse the config: %v
- root should be an object
- only one storage block is allowed
- failed to parse config:
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ee3f8384983017a5.
Report an issue: GitHub.