{"record":{"id":"0eeebdb9e8181601","repo":"hashicorp/nomad","slug":"error-parsing-root-should-be-an-object-0eeebd","errorCode":null,"errorMessage":"error parsing: root should be an object","messagePattern":"error parsing: root should be an object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/namespace_apply.go","lineNumber":208,"sourceCode":"\t\treturn 1\n\t}\n\n\tc.Ui.Output(fmt.Sprintf(\"Successfully applied namespace %q!\", namespace.Name))\n\n\treturn 0\n}\n\n// parseNamespaceSpec is used to parse the namespace specification from HCL\nfunc parseNamespaceSpec(input []byte) (*api.Namespace, error) {\n\troot, err := hcl.ParseBytes(input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Top-level item should be a list\n\tlist, ok := root.Node.(*ast.ObjectList)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"error parsing: root should be an object\")\n\t}\n\n\tvar spec api.Namespace\n\tif err := parseNamespaceSpecImpl(&spec, list); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &spec, nil\n}\n\n// parseNamespaceSpec parses the quota namespace taking as input the AST tree\nfunc parseNamespaceSpecImpl(result *api.Namespace, list *ast.ObjectList) error {\n\t// Decode the full thing into a map[string]interface for ease\n\tvar m map[string]any\n\tif err := hcl.DecodeObject(&m, list); err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/namespace_apply.go#L190-L226","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: fields floating at top level\nname = \"prod\"\ndescription = \"production\"\n// after\nnamespace \"prod\" {\n  description = \"production\"\n}","handlingStrategy":"validation","validationCode":"// ensure the spec root is an object block before applying\ngrep -q '^namespace' \"$SPEC_FILE\" || { echo \"$SPEC_FILE must contain a top-level namespace block\"; exit 1; }","typeGuard":"func isObjectList(root *ast.Node) bool {\n    _, ok := root.(*ast.ObjectList)\n    return ok\n}","tryCatchPattern":"spec, err := parseNamespaceSpec(path)\nif err != nil && strings.Contains(err.Error(), \"root should be an object\") {\n    return fmt.Errorf(\"%s: wrap contents in a top-level `namespace { ... }` block\", path)\n}","preventionTips":["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."],"tags":["nomad-cli","hcl","parsing","config-validation"],"backgroundTag":"hcl-parse-error","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}